سؤال

لدي الرمز التالي

 int wordLenght = 256, arrayLength = 2, i = 0, counter = 0;
 char **stringArray = NULL; 

 stringArray = calloc(arrayLength, sizeof(*stringArray));

 for(counter; counter<wordLenght; counter++) 
    stringArray[counter] = calloc(wordLenght, sizeof(stringArray));

 while(1)
 {
   printf("Input: ");
   fgets(stringArray[i], wordLenght, stdin);

   printf("stringArray[%d]: %s\n", i, stringArray[i]);

   if(i == arrayLength)
   {
     printf("Reallocation !!!\n");
     arrayLength *= 2;

     stringArray = realloc(stringArray, arrayLength*sizeof(*stringArray));

   } 

   i++;
 }    

أحصل على خطأ إعادة التخصيص هذا:

*** glibc detected *** ./stringArray: realloc(): invalid next size: 0x0000000000b49010 ***
======= Backtrace: =========
/lib/libc.so.6(+0x775b6)[0x7f4dd12565b6]
/lib/libc.so.6(+0x7dd66)[0x7f4dd125cd66]
/lib/libc.so.6(realloc+0xf0)[0x7f4dd125d080]
./stringArray[0x4007f9]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f4dd11fdc4d]
./stringArray[0x400629]

ما هي مشكلتي هنا ؟؟؟

شكرا ، تحية

هل كانت مفيدة؟

المحلول

 stringArray = calloc(arrayLength, sizeof(*stringArray));

ربما أردت استخدام SizeOf (char*)

for(counter; counter<wordLenght; counter++) stringArray[counter] = calloc(wordLenght, sizeof(stringArray));

هنا تقوم بحلق 256 مرة (WordLenght) ولكن يجب عليك فقط مرتين (ArrayLength). بالإضافة إلى ذلك ، ربما أردت استخدام SizeOF (char) بدلاً من حجم (StringArray).

if(i == arrayLength) {...}

يجب إجراء هذا الشيك قبل الاتصال بـ FGTS ، لأنك الآن تستخدم الذاكرة أولاً وتخصيصها لاحقًا.

بالإضافة إلى ذلك بعد إعادة تخصيص StringArray ، تحتاج إلى تخصيص بقية الأوتار باستخدام شيء من هذا القبيل

for(counter = i; counter<arrayLength; counter++) stringArray[counter] = (char*)calloc(wordLenght, sizeof(char));

وأخيراً تحتاج إلى تحرير جميع الذاكرة المخصصة قبل الخروج من التطبيق.

نصائح أخرى

ربما لم تقصد sizeof(*stringArray)

في الحقيقة أعتقد أنك قد ترغب في إعادة الراحة في calloc اتصل أيضًا ، أعتقد أنك تقوم بتخصيص حجم المؤشر هناك (أوقات طول الكلمة).

بعد أول مرة ينفذ هذا الخط:

stringArray = realloc(stringArray, arrayLength*sizeof(*stringArray));

ثم ستكون StringArray [ArrayLength/2] قيمة قمامة - لم تقم بتعيينها لتشير إلى التخزين للكلمة.

يجب أن يستخدم هذا الجزء إما استخدام SizeOF (** StringArray) ، أو 1 كـ ** stringArray is char ، ويجب أن يرتفع العداد فقط إلى ArrayLength:

 for(counter; counter<wordLenght; counter++) 
     stringArray[counter] = calloc(wordLenght, sizeof(stringArray));

بدلاً من ذلك تخصيص في كتلة واحدة:

 char* block = malloc(wordLength * arrayLength);

 for ( counter; counter < arrayLength; ++counter ) 
     stringArray[counter] = block + ( counter * wordLength );

في الوقت الحالي ، من المحتمل أن يكون هناك بعض المساحة بعد StringArray ، التي تقوم بتخزينها (طول الطول ذات الطول) المؤشرات الإضافية عند الاتصال بها ، ولا تحرك Realloc StringArray.

من المحتمل تمامًا أن يكون 0xb49010 أحد المؤشرات التي تعود إلى calloc'd ، وأنك مكتوبة بالذاكرة حيث يحتفظ Malloc بحجم كتلة ..

ولكن نظرًا لأنك تشطلك من نهاية StringArray ، فأنت في سلوك غير محدد على أي حال.

حسنًا ، هذا هو الحل كله:

int wordLength = 256, arrayLength = 2, i = 0, counter = 0;
    char **stringArray = NULL;
    char buffer[wordLength];

    stringArray = calloc(arrayLength, sizeof(char*));
    for(counter; counter<arrayLength; counter++) stringArray[counter] = (char*)calloc(wordLength, sizeof(char));

    while(1)
    {
        if(i == arrayLength)
        {
            printf("Reallocation !!!\n");
            arrayLength *= 2;

            stringArray = realloc(stringArray, arrayLength*sizeof(char*));
            for(counter = i; counter<arrayLength; counter++) stringArray[counter] = (char*)calloc(wordLength, sizeof(char));
        }   

        printf("Input: ");
        fgets(buffer, wordLength, stdin);

        if(!strcmp(buffer,"q\n")) break; // also free here      
        else stringArray[i] = buffer;

        printf("stringArray[%d]: %s\n", i, stringArray[i]);

        i++;
    }

كيف هي أفضل طريقة لتحرير المساحة؟!

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