开发者

Make malloc() return NULL instead of crashing the program?

开发者 https://www.devze.com 2023-01-11 23:50 出处:网络
I am allocating memory in a C program using malloc. It\'s possible for my program to allocate more memory than the system has room for, at which point the program crashes. For my purposes it would be

I am allocating memory in a C program using malloc. It's possible for my program to allocate more memory than the system has room for, at which point the program crashes. For my purposes it would be better if malloc would just return NULL (like it's apparently supposed to), so I can catch the error. Instead what it does is it throws an error saying "No memory available to prog开发者_StackOverflowram now: unsafe to call malloc." And crashes the program.

How can I fix this?

Edit: I know that the program is crashing by itself and not because I'm trying to reference a null pointer. The program never directly calls malloc, but instead calls a function I wrote that calls malloc and then checks to see if it returns NULL. It's never saying that malloc returned NULL.

Edit 2: If it's helpful, here is the complete error output:

Program received signal: “EXC_BAD_ACCESS”.

sharedlibrary apply-load-rules all

warning: Unable to restore previously selected frame.

Data Formatters temporarily unavailable, will re-try after a 'continue'. (The program being debugged was signaled while in a function called from GDB.

GDB remains in the frame where the signal was received.

To change this behavior use "set unwindonsignal on"

Evaluation of the expression containing the function (dlopen) will be abandoned.)

No memory available to program now: unsafe to call malloc


Once you scribble on the heap via buffer overruns, wild pointers or other bugs, malloc's behavior becomes undefined and it could return anything.

Malloc is simply a user-space library; there isn't any magic contained within it. If I scribble all over your application's linked list of customer names, you'll get weird behavior when you later access that list. Malloc behaves in the same way, but since the use of malloc is distributed through the code, cause and effect have global reach.

All of the answers are dancing around the fact that pointer errors are the single most prevalent source of defects in C code. You are lucky you are getting a SIGBUS which is the evidence of defect that may be widely separated from where and when the fault occurs. Use valgrind to help you find where the real defect is.


It checks to see if Malloc returns NULL? You may have a problem with the equality test. Try something like 'if (malloc(...)) then ...; else ...;' rather than a specific check.

If that fails to help then run just the preprocessor and work out what NULL is being 'edited' to be.


According to this apple page, the program will abort based on a malloc error if the MallocErrorAbort environment variable is turned on in xcode. To turn off this variable, right-click on the executable in the Tree view, select "Get Info," and go to the "Arguments" tab.


Strange ... the following works for me if I compile it from the command line. The runtime supplied malloc does have a lot of options as Spencer mentioned. If you are using XCode, I would look for an option that controls this.

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


int
main()
{
    signed long long alloc_sz = (1 * 1024 * 1024 * 1024);
    while (alloc_sz > 0ull) {
        char *ptr = malloc(alloc_sz);
        if (ptr == NULL) {
            fprintf(stderr, "failed to allocate %llu bytes\n",
                    (unsigned long long)alloc_sz);
            break;
        } else {
            free(ptr);
            fprintf(stderr, "allocated %llu bytes\n",
                    (unsigned long long)alloc_sz);
        }
        alloc_sz *= 2ull;
    }
    return 0;
}

BTW: is this in a debug or release build? It may be that XCode is trying to help you out somehow.


As the others have said, it's very likely that you have overwritten some of malloc's internal state, causing it to do weird things.

On Linux, the way you would track this down would be to use valgrind. If your code is sufficiently cross-platform that you can run it on Linux (perhaps in a VM) I would recommend doing this.

If this option is not available to you, Mac OS X has its own built-in debugging tools. At a high level there is Instruments. At lower level, malloc will enable debugging in response to certain environment variables: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/malloc.3.html Scroll down to the ENVIRONMENT section. So for example you would run your program with

MallocGuardEdges=1 ./myProg

You can also use libgmalloc which is like the malloc debugging features on crack. You can read about it here: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/libgmalloc.3.html

You would run your program like this:

DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib ./myProg
0

精彩评论

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