RealLoc () ING الذاكرة للمخزن المؤقت المستخدم في RECV ()
سؤال
أحتاج إلى RECV () من المقبس وتخزينها في المخزن المؤقت ، لكنني بحاجة إلى التأكد من الحصول على جميع البيانات حتى لديّ أشياء في حلقة. لذلك للتأكد من عدم نفاد الغرفة في المخزن المؤقت ، أحاول استخدام RealLoc لتغيير حجم الذاكرة المخصصة للمخزن المؤقت. حتى الآن لدي:
// receive response
int i = 0;
int amntRecvd = 0;
char *pageContentBuffer = (char*) malloc(4096 * sizeof(char));
while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
i += amntRecvd;
realloc(pageContentBuffer, 4096 + sizeof(pageContentBuffer));
}
ومع ذلك ، لا يبدو أن هذا يعمل بشكل صحيح لأن Valgrind يشكو من "Valgrind:" المستحيل "حدث:". أي نصيحة حول كيفية القيام بذلك بشكل صحيح؟
شكرا ، هريستو
تحديث ... أدركت أنني كنت أستخدم RealLoc بشكل غير صحيح. هنا نسخة منقحة:
int i = 0;
int amntRecvd = 0;
char *pageContentBuffer = (char*) malloc(4096 * sizeof(char));
while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
i += amntRecvd;
char *temp = realloc(pageContentBuffer, 4096 + sizeof(pageContentBuffer));
if (temp != NULL) {
pageContentBuffer = temp;
}
}
ومع ذلك ، لا يزال Valgrind يشكو:
==25812== Syscall param socketcall.recvfrom(buf) points to unaddressable byte(s)
==25812== at 0x33B880DAA1: recv (in /lib64/libpthread-2.5.so)
==25812== by 0x401D78: tunnelURL (proxy.c:371)
==25812== by 0x40142A: client_thread (proxy.c:194)
==25812== by 0x33B8806616: start_thread (in /lib64/libpthread-2.5.so)
==25812== by 0x33B7CD3C2C: clone (in /lib64/libc-2.5.so)
==25812== Address 0x5642768 is 0 bytes after a block of size 4,104 alloc'd
==25812== at 0x4A0590B: realloc (vg_replace_malloc.c:306)
==25812== by 0x401D47: tunnelURL (proxy.c:373)
==25812== by 0x40142A: client_thread (proxy.c:194)
==25812== by 0x33B8806616: start_thread (in /lib64/libpthread-2.5.so)
==25812== by 0x33B7CD3C2C: clone (in /lib64/libc-2.5.so)
المحلول
sizeof
هي قيمة وقت الترجمة ، وليس وقت التشغيل.
من الممكن ل realloc
للعودة 0.
جرب هذا...
// receive response
int i = 0;
int amntRecvd = 0;
int currentSize = 4096;
int oldSize = currentSize;
char *pageContentBuffer = (char*) malloc(currentSize);
while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
i += amntRecvd;
oldSize = currentSize;
currentSize += 4096;
char *newBuffer = malloc(currentSize);
memcpy(newBuffer,pageContentBuffer,oldSize);
free(pageContentBuffer);
pageContentBuffer = newBuffer;
}
أفضل رهان لك هو إعادة تخصيص الذاكرة ونسخها ثم تحريرها بشكل صريح - realloc
غريب.
نصائح أخرى
بصرف النظر عما قاله whirlwind ، هناك أيضًا قضية ثانية:
sizeof
لا يعيد كمية الذاكرة المخصصة مسبقًا ، فهو في الواقع عبارة عن بنية لوقت التجميع والتي تعادل sizeof(char *)
, ، أي حجم مؤشر الشخصية.
ستحتاج إلى تتبع طول المخزن المؤقت يدويًا في متغير. لا توجد طريقة قياسية "لمستلقي" مقدار الذاكرة التي تم تخصيصها بواسطة Malloc/RealLoc.
ربما هناك مشكلة لأنك تسيء استخدام RealLoc (). تحتاج إلى معرفة ما إذا كان يعيد مؤشرًا جديدًا ، وإذا كان الأمر كذلك ، قم بتخزين هذا المؤشر.
// receive response
int i = 0;
int amntRecvd = 0;
char *pageContentBuffer = (char*) malloc(4096 * sizeof(char));
while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
i += amntRecvd;
pageContentBuffer = realloc(pageContentBuffer, 4096 + sizeof(pageContentBuffer));
}
مشكلتك الرئيسية هي أنك تقوم بإعادة تخصيص مقدار الذاكرة الخاطئ. انت تريد
realloc(pageContentBuffer, 4096 + i);
sizeof(pageContentBuffer)
انه ببساطة sizeof(char *)
, ، مما يعني أنك تخصيص أقل بكثير مما تحتاجه للقراءة الثانية.