What happens to my program when "free (ppMapData [i])" is executed?

I tried to make a dynamic 2D array char

like this:

char** ppMapData = (char**)malloc(sizeof(char*)*iMapHeight);
for (int i=0; i< iMapHeight; i++)
{
    ppMapData[i] = (char*)malloc(sizeof(char)*iMapWidth);
    //do something
}

// do something

for (int i=0; i<iMapHeight; i++)
    free(ppMapData[i]);
free(ppMapData);

      

This looks good to me; however, when it comes to runtime, my program crashes at the line that calls free(ppMapData[i])

. Any ideas what the problem is. Thank you very much.

0


source to share


11 replies


With a quick glance, freedom looks great. The next thing you should check is to make sure you don't overlap any of these arrays at the end. This can cause problems with memory allocation systems.



If you are using visual studio you can call _CrtCheckMemory to make sure you are not parsing things. This call only works in the DEBUG assembly.

+8


source


Have you checked for NULL values ​​after malloc?



+4


source


You tagged your question "C ++". Why not use the appropriate C ++ constructs instead? For example. a vector<vector<char> >

or even (perhaps I suggest) a vector<string>

?

EDIT Well, vector<string>

probably not what you want. However, I highly recommend the C ++ solution - ier.

+2


source


I don't see the problem at first glance, but that doesn't mean it doesn't exist. Make sure you are not doing double access by freeing memory somewhere in the "do something" section.

+2


source


If it's a 2D array with patch size in both dimensions, I always prefer:

char* array = (char*)malloc(iMapHeight*iMapWidth);

      

And accessing it with:

char val = array[height*iMapWidth + width];

      

Wrap it up with a macro if you like:

#define GET_VAL(h, w) array[h*iMapWidth + w]

      

Multiplication will be faster than removing a pointer by two pointers to find the value.

+2


source


Several possible answers:

  • Are you sure you are not overlapping the ends of the arrays you allocated? malloc will store important information right after the allocated memory, and if you overwrite it, something bad will happen.

  • Are you sure you are not changing the values ​​in ppMapData? Trying to free a pointer that has never been allocated is generally bad too.

  • What is the value of i when your program crashed? Is this consistent? knowing that it will be helpful and perhaps instructive

Some stylistic comments:

  • Check the return value of malloc (it will be NULL if not satisfied).

  • Don't use the return value malloc (unless you are actually writing C, not C ++).

+2


source


Assuming // to do more than just comment, take out

// do something

and check if it worked. Add stuff back one at a time until it works again.

0


source


From the code in the question, it looks like you are not checking if malloc succeeded. Make sure malloc doesn't return NULL as the first step. This may not be your problem as

//do something

      

it probably uses the newly allocated memory, but if it doesn't, malloc may fail if you don't know how much it would be freed. (I know it's unlikely that malloc will fail unless you're developing a low memory environment, but it's still worth checking out.)

Second, what is the value i

when it fails, almost the same?

Finally, you can get us the main dump, the problem will be easier to identify :)

0


source


Does it still crash if you remove the "do something" code? If you are not, it probably means that you are breaking memory in your code to "do something" and that is where your error is, not in the code above.

If you're on a platform that supports it, run it through Valgrind, it's invaluable for finding subtle bugs.

0


source


Alternatively to joemucchiello,

char **ppMapData = malloc(iMapHeight * sizeof(char*) +
                          iMapHeight * iMapWidth * sizeof(char)));

for (int i = 0; i < iMapHeight; i++) {
    ppMapData[i] = (char *)(ppMapData + iMapHeight) + i * iMapWidth;
    /* do something */
}

/* do something */

free(ppMapData);

      

This makes one big selection containing both the pointer array and the array-of-of-characters.

However, like many others, the code you posted works fine. There // do something

must be something in the " " segment that you haven't sent that is causing this error.

For example, if you have already released it ppMapData[i]

, you cannot release it again. Some people would avoid this by setting ppMapData[i] = NULL

right after either free(ppMapData[i])

: it works because it free(NULL)

is legal and does nothing. My preference is not to do this, but to fix any design that leads you to a double free access situation.

0


source


Is iMapHeight / iMapWidth constant? If not, they could be changed between them causing problems. Also, as suggested by others, check if malloc returns null.

-1


source







All Articles