开发者

Weird crash with pointers / malloc() on if check of the pointer value

开发者 https://www.devze.com 2022-12-17 16:17 出处:网络
I have some really weird crash here, ive got it before, but i thought i fixed it by adding = NULL to the variable declarations:

I have some really weird crash here, ive got it before, but i thought i fixed it by adding = NULL to the variable declarations:

#include <stdlib.h>

...

GLuint *TEX = NULL;
int TEX_MEMSIZE = sizeof(GLuint)*1024*1024;

...

void something1(){
    ...
    TEX = (GLuint *)malloc(TEX_MEMSIZE);
    ...
}

void something2(){
    ...
    // this line runs fine.
    if(TEX != NULL){ // CRASH ON THIS LINE OF CODE
        // wont run anything after the above line.
        free(TEX);
    }
    // ...nor here since it crashed...
    ...
}

It crashes on my laptop/vista, but not on my desktop computer/winXP.

When i remove that if check and the free(), it wont crash anymore.

I just dont get it, what im doing wrong? What could cause this? i only know incorrectly predefined arrays can cause some illogical errors, i dont believe there is such incorrect arrays in my code now, so im waiting for more ideas. (and because checking 20k lines of codes can be quite slow too)

Edit: Now i noticed it will not 开发者_运维问答crash before free() but AFTER it. I start thinking its some predefined array problem... since the position of crash is changing. (or i just have dementia).

EDIT 2: FIXED, there was two free() calls, before and after malloc() >_> i feel so stupid now.


free(TEX);

frees the memory, but doesn't change the pointer. Change it to

if (TEX != NULL)
{
    free(TEX);
    TEX = NULL;
}

So if you call something2() a second time, it won't try to free(TEX) again.


How is TEX_MEMSIZE defined?

It should be something like:

#define NUM_ENTRIES 50
#define TEX_MEMSIZE NUM_ENTRIES * sizeof(GLuint)


From the given data, and assuming that the program is multi-threaded, there might be a race condition between the if (TEX != NULL) check and the free, which might result in a free on a NULL pointer. You might want to check that out.


Assuming that TEX is truely a pointer type (meaning you don't have it re-declared at a more local scope), The only way the line

if(TEX != NULL){

Could cause a crash is if accessing TEX caused an invalid memory access. Since TEX is a global variable, the only way it could be at invalid memory is if the DLL that defines TEX is not loaded into the process. Put a breakpoint before the IF statement and verify that the DLL that contains the TEX declaration is loaded into the process.

Of course, if you did have a debugger, you probably would have told us what the unhandled exception type was. If you don't have access to a debugger, then put a

sleep (60 * 1000 * X);

before the IF statement and use the Windows Internals' "Process Explorer" utility (now distributed by Microsoft) to see what modules are loaded in the process. Set 'X' to the number of minutes it'll take you to do this, 2 or 3 should be sufficient.


repeat the same TEX != NULL test all over the place, it will surely be OK right after the malloc; its certainly broken later on.

Keep repeating the test in all the '...' code. Eventually you find that there is a place where it worked before line x but not after it. THis will point the finger at the problem

Or your debug symbols are wrong and the crash is not happening where you think it is. Close VS, reopen, rebuild all and try again


My crystal ball says the you need to do

#include <stdlib.h>

in all the source files where you use malloc(), realloc() and free(). If that doesn't solve your problem, then you have to post a minimum compilable code that exhibits the behavior.

If that does solve your problem: a missing #include <stdlib.h> means that malloc() has no prototype in scope. The compiler assumes that it returns int. It doesn't, of course. Normally, the compiler would have warned you when you assign the result of malloc() to a pointer type, but because of the cast, the compiler assumes you know what you're doing and doesn't warn you. For this reason, I don't recommend casting the return value of malloc() in C.

So, your malloc() call would be:

#include <stdlib.h>
TEX = malloc(TEX_MEMSIZE);

Also, you're assuming that sizeof(int) divides TEX_MEMSIZE. Do you want TEX_MEMSIZE bytes, or TEX_MEMSIZE ints? If latter, you need to multiply by sizeof(int) in your malloc() call:

TEX = malloc(TEX_MEMSIZE * sizeof *TEX);

You should also change the type of TEX_MEMSIZE. In C, int is only guaranteed to store values <= 32767. It may be able to store larger values, but that is not certain. Since you use it for malloc(), I would recommend size_t type, or better yet, make it a #define.

Based upon your edit, it could be that you're changing TEX after malloc(), and then passing that value to free(). Are you sure TEX isn't changed between malloc() and free()?


Based on your update to the question, where the not the NULL check but instead the free() call crashes:

Something in your program is corrupting either the heap infrastructure or the actual value of TEX.


The problem is not the free itself. Your bug lies in the code not quoted in this post, as you must have overwritten memory above your allocated region. If you get a crash in free() it is mostly because of 2 things:

  • you passed a wrong pointer ( not allocated with malloc() )
  • you have overwritten memory before or after the block you allocated

I am pretty sure no. 2 will be your issue in this case.

0

精彩评论

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