RealLoc () ING الذاكرة للمخزن المؤقت المستخدم في RECV ()

StackOverflow https://stackoverflow.com/questions/2679719

  •  30-09-2019
  •  | 
  •  

سؤال

أحتاج إلى 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)
هل كانت مفيدة؟

المحلول

ابحث عن Realloc.

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 *), ، مما يعني أنك تخصيص أقل بكثير مما تحتاجه للقراءة الثانية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top