简体   繁体   中英

C Program exits after calling malloc

#define ACTION_LIST_N 3
#define MALLOC 1
#define REALLOC 2

typedef struct action action_t;
struct action {
    char name;        // action name
    state_t precon;   // precondition
    state_t effect;   // effect
};

main(int argc, char *argv[]) {
    action_t** action_list;

    make_action_list(action_list, ACTION_LIST_N, MALLOC);
    action_list[0] = (action_t*)malloc(sizeof(**action_list));
    printf("1"); <- DOES NOT EXECUTE

    return 0;
}

void 
make_action_list(action_t** action_list, int n, int request) {
    if (request==MALLOC) {
        action_list = (action_t**)malloc(n * sizeof(*action_list));
        if_null(action_list, "Initial allocation failure");
    } else if (request==REALLOC) {
        action_list = (action_t**)realloc((action_t**)action_list, (n*2)*sizeof(*action_list));
        if_null(action_list, "Realloc failure");
    }
}

Sorry for the long post but I'm really stuck and not sure how to fix this.

I made an array of pointers to structs (action_list) and allocated memory to action_list with make_action_list(). However, when I tried calling malloc on the first pointer in the array, the program exits without any warning messages and "1" never gets printed. What am I doing wrong? Thanks in advance.

I was following the tutorial on dynamic arrays here: C: pointer to array of pointers to structures (allocation/deallocation issues)

The value assigned to action_list inside the function does not change the value of action_list in main .

To fix it, you have two options:

Option 1. Let the function return a pointer

Like:

void* make_action_list(int n, int request) {
    ...
    return ALLOCATED_MEMORY;
}

and call like

action_list = make_action_list(ACTION_LIST_N, MALLOC);

Option 2. Pass a pointer to action_list

Like

void make_action_list(action_t*** action_list, int n, int request) {
                              ^^^
                              Notice

and call like:

make_action_list(&action_list, ACTION_LIST_N, MALLOC);
         

Let's go one by one.

action_t** action_list;

Your action "list" looks to be an array from how you use it, so this should be a single pointer.

make_action_list(action_list, ACTION_LIST_N, MALLOC);

Making the previous definition a single pointer would change this line to the much more standard make_action_list(&action_list, ACTION_LIST_N, MALLOC); , passing a pointer to your pointer so the function can modify it.

action_list = (action_t**)malloc(n * sizeof(*action_list));

You don't want to allocate n pointers, you want to allocate n actions. As such, this line should be *action_list = malloc(n * sizeof(action_list)); (note that you also don't need to cast the pointer coming out of malloc , doing it shows you don't understand C cast rules).

action_list = (action_t**)realloc((action_t**)action_list, (n*2)*sizeof(*action_list));

Similar to above, you want to realloc actions, not pointers. However, the way you wrote this is a gigantic problem, because realloc can fail and return 0 , and assigning it to your action list directly would make your original pointer disappear, thus leaking memory. Modern C++ has a warning specifically for this case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM