إعادة تخصيص صفيف شار 2D
-
02-10-2019 - |
سؤال
لدي الرمز التالي
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++;
}
كيف هي أفضل طريقة لتحرير المساحة؟!