【问题标题】:C Program exits after calling mallocC程序调用malloc后退出
【发布时间】:2021-02-08 00:28:00
【问题描述】:
#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");
    }
}

很抱歉,这篇文章很长,但我真的卡住了,不知道如何解决这个问题。

我创建了一个指向结构 (action_list) 的指针数组,并使用 make_action_list() 为 action_list 分配了内存。但是,当我尝试在数组中的第一个指针上调用 malloc 时,程序退出时没有任何警告消息,并且永远不会打印“1”。我究竟做错了什么?提前致谢。

我在这里关注动态数组的教程:C: pointer to array of pointers to structures (allocation/deallocation issues)

【问题讨论】:

  • 在函数中,action_list = (action_t**)malloc(n * sizeof(*action_list)); 设置的值会覆盖传递的函数参数,不会改变main() 中的任何内容。 action_list 的值被遗忘(并且您有内存泄漏)。然后用action_list[0] 取消引用uninitialised 指针。顺便说一句,在调试中确保printf("1"); 不执行请添加fflush(stdout);

标签: arrays c pointers dynamic malloc


【解决方案1】:

分配给action_list的值内部函数不改变mainaction_list的值。

要修复它,您有两种选择:

选项1.让函数返回一个指针

喜欢:

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

然后打电话

action_list = make_action_list(ACTION_LIST_N, MALLOC);

选项 2. 传递指向 action_list 的指针

喜欢

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

然后像这样调用:

make_action_list(&action_list, ACTION_LIST_N, MALLOC);
         

【讨论】:

    【解决方案2】:

    我们一个一个去。

    action_t** action_list;
    

    从你的使用方式来看,你的动作“列表”看起来是一个数组,所以这应该是一个单一的指针。

    make_action_list(action_list, ACTION_LIST_N, MALLOC);
    

    将先前的定义设为单个指针会将这一行更改为更标准的make_action_list(&amp;action_list, ACTION_LIST_N, MALLOC);,将指针传递给您的指针,以便函数可以修改它。

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

    您不想分配n 指针,您想分配n 操作。因此,这一行应该是*action_list = malloc(n * sizeof(action_list));(请注意,您也不需要转换来自malloc 的指针,这样做表明您不了解C 转换规则)。

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

    与上面类似,您想要重新分配操作,而不是指针。但是,您编写此代码的方式是一个巨大的问题,因为realloc 可能会失败并返回0,并且直接将其分配给您的操作列表会使您的原始指针消失,从而导致内存泄漏。现代 C++ 有专门针对这种情况的警告。

    【讨论】: