开发者

Expanding an array of ints using realloc crashes!

开发者 https://www.devze.com 2023-02-18 03:06 出处:网络
I\'m trying to expand an array of ints on the heap using realloc but the programme is crashing when I use my custom function \"ExpandArrayOfInts\" but works fine when I write the expander code within

I'm trying to expand an array of ints on the heap using realloc but the programme is crashing when I use my custom function "ExpandArrayOfInts" but works fine when I write the expander code within main.

Here is the code (file: main.c) with #defines for both approaches.

#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;
}

The part that doesn't work gives the following output:

new size: 15

new size: 20

and then I get the cra开发者_JS百科sh message:

"Windows has triggered a breakpoint in c_cplusplus_mixing.exe. This may be due to a corruption of the heap, which indicates a bug in c_cplusplus_mixing.exe or any of the DLLs it has loaded. This may also be due to the user pressing F12 while c_cplusplus_mixing.exe has focus. The output window may have more diagnostic information."

The call stack doesn't seem very meaningful (at least for a novice like myself).

Call Stack:

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

Note, I'm using visual studio 2008 and running Debug build. (Release doesn't work either).

Could anyone please point me to where I'm going wrong! and please let me know if more details are needed.

Many thanks in advance,

Hasan.


The problem is that ExpandArrayOfInts is receiving a pointer to an int instead of a pointer to the pointer that has to reallocate. It should look like this:

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

and then you would call it like this:

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

I'd recommend you to look for questions related to pointers in stackoverflow so that you get a better understanding of them.


From the realloc() documentation on my system:

realloc() returns a pointer to the newly allocated memory, which is suitably aligned for any kind of variable and may be different from ptr, or NULL if the request fails.

Your ExpandArrayOfInts() declaration and implementation does not allow realloc to modify the actual pointer in main() - it implicitly assumes that its value cannot change. When realloc() moves the memory area and does return a different pointer, it calls free() on the pointer it was called with. The rest of your program, though, goes on using the original value which is now invalid, hence the crash.

You should use a pointer-to-a-pointer to pass the memory area pointer by reference, instead:

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

精彩评论

暂无评论...
验证码 换一张
取 消