Расширение массива целых с использованием сбоев realloc! - PullRequest
0 голосов
/ 20 марта 2011

Я пытаюсь расширить массив целых чисел в куче, используя realloc, но программа падает, когда я использую свою пользовательскую функцию "ExpandArrayOfInts", но работает нормально, когда я пишу код расширителя в main.

Вот код (файл: main.c) с #defines для обоих подходов.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int ExpandArrayOfInts(int* arrayToExpand, int expandBy, int inArraySize, int* outArraySize);


int main (int argc, char** argv)
{
#if 1//CODE THAT WORKS

int arraySize = 10;
int* arrayDnmc = NULL;
int* arrayDnmcExpndd;


for (int i = 0; i< 10; ++i)
{
    arrayDnmcExpndd = (int*)realloc(arrayDnmc, (arraySize + (i * 10)) * sizeof(int));
    if (arrayDnmcExpndd != NULL)
    {
        arrayDnmc = arrayDnmcExpndd;
        memset(arrayDnmc, 0, (arraySize + (i * 10)) * sizeof(int));
    }
    else
    {
        printf("Failed to (re)alloc memory for arrayDnmc!\n");
        free(arrayDnmc);
        return -1;
    }
}
free(arrayDnmc);

#else   //CODE THAT DOESN'T WORK (Which I'm trying to make it work)

int maxSize = 100;
int arraySize = 10;
int* arrayDnmc = NULL;

arrayDnmc = (int*)malloc(arraySize * sizeof(int));
if (arrayDnmc != NULL)
{
    memset(arrayDnmc, 0, arraySize * sizeof(int));
}
else
{
    printf("malloc failure!\n");
    return -1;
}

while (arraySize < maxSize)
{
    if (0 != ExpandArrayOfInts(arrayDnmc, 5, arraySize, &arraySize))
    {
        printf("Something went wrong.\n");
        break;
    }
    //do something with the new array
    printf("new size: %i\n", arraySize);
}
free(arrayDnmc);
#endif
return 0;
}

int ExpandArrayOfInts(int* arrayToExpand, int expandBy, int inArraySize, int* outArraySize)
{
int newSize = inArraySize + expandBy;
int* arrayTemp = (int*)realloc(arrayToExpand, newSize * sizeof(int));
if (arrayTemp != NULL)
    {
        arrayToExpand = arrayTemp;
        *outArraySize = newSize;
        return 0;
    }
    return -1;
}

Часть, которая не работает, дает следующий вывод:

новый размер: 15
новый размер: 20

и затем я получаю сообщение об ошибке:

"Windows запустила точку останова в c_cplusplus_mixing.exe. Это может быть связано с повреждением кучи, что указывает на ошибку в c_cplusplus_mixing.exe или в любой из загруженных им DLL-библиотек. Это также может быть вызвано тем, что пользователь нажал F12, когда c_cplusplus_mixing.exe имеет фокус. В окне вывода может быть больше диагностической информации. "*

Стек вызовов не выглядит очень значимым (по крайней мере, для такого новичка, как я).
Стек вызовов:

ntdll.dll!775c542c()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7758fdd0()
ntdll.dll!7755b3fc()

Обратите внимание, я использую Visual Studio 2008 и запускаю DebugBuilд.(Релиз тоже не работает).
Может кто-нибудь указать мне, где я иду не так!и, пожалуйста, дайте мне знать, если потребуется более подробная информация.

Большое спасибо заранее,
Хасан.

Ответы [ 2 ]

3 голосов
/ 20 марта 2011

Проблема в том, что ExpandArrayOfInts получает указатель на int вместо указателя на указатель, который должен перераспределиться. Это должно выглядеть так:

int ExpandArrayOfInts(int** arrayToExpand, int expandBy, int inArraySize, int* outArraySize)

и тогда вы бы назвали это так:

ExpandArrayOfInts(&arrayDnmc, 5, arraySize, &arraySize))

Я бы порекомендовал вам искать вопросы, связанные с указателями в stackoverflow, чтобы вы лучше понимали их.

1 голос
/ 20 марта 2011

Из документации realloc() в моей системе:

realloc () возвращает указатель на вновь выделенная память, которая соответствующим образом выровнен для любого вида переменная и может отличаться от ptr или NULL, если запрос не выполнен.

Ваше объявление и реализация ExpandArrayOfInts() не позволяет realloc изменять фактический указатель в main() - оно неявно предполагает, что его значение не может измениться. Когда realloc() перемещает область памяти и возвращает другой указатель, он вызывает free() для указателя, с которым он был вызван. Однако остальная часть вашей программы продолжает использовать исходное значение, которое теперь недопустимо, поэтому происходит сбой.

Вы должны использовать указатель на указатель для передачи указателя области памяти по ссылке, вместо этого:

int ExpandArrayOfInts(int** arrayToExpand, int expandBy, int inArraySize, int* outArraySize)
.
.
.
*arrayToExpand = (int*)realloc(*arrayToExpand, newSize * sizeof(int));
...