为什么我需要在MacOs上初始化malloc的结果?

为什么我需要在MacOs上初始化malloc的结果?,c,malloc,C,Malloc,我已经实现了一个C计算器来分析输入。 我有一个结构(类似链表),但在macOS上,我必须通过init_null函数或类似变量的值进行初始化。 我只有一个问题:为什么 在Linux上,没有问题 typedef struct node_t { int value; char operator; struct node_t *left; struct node_t *right; } node_t; node_t *init_null(node_t *root) {

我已经实现了一个C计算器来分析输入。 我有一个结构(类似链表),但在macOS上,我必须通过init_null函数或类似变量的值进行初始化。 我只有一个问题:为什么

在Linux上,没有问题

typedef struct node_t {
    int value;
    char operator;
    struct node_t *left;
    struct node_t *right;
} node_t;

node_t *init_null(node_t *root) {
    root->value = NULL;
    root->operator = NULL;
    root->left = NULL;
    root->right = NULL;
    return root;
}

node_t *build_tree(const char *argv[], int *position) {
    node_t *new = malloc(sizeof(node_t));
    new = init_null(new); /*sinon erreur*/

    if (isdigit(*argv[*position])) {
        new->value = atoi(argv[*position]);
    } else/*Opérateur*/  {
        new->operator = *argv[*position];
        *position = *position + 1;
        new->left = build_tree(argv, position);
        *position = *position + 1;
        new->right = build_tree(argv, position);
    }
    return new;
}
运行时,
/main*2+3 4
应打印
(2*(3+4))

问题如下:

您至少可以使用两种内存分配方法,
malloc
calloc
。区别在于
malloc
不会初始化(或设置)成功分配的内存。正如@EricPostpischil所解释的,内存块上有一个不确定的显式或隐式效果,特定于处于这种编译状态的编译器

calloc
将成功分配的内存块设置为零。请注意,参数略有不同

回到您所关心的问题,在Linux
malloc
中,恰好分配了一个内存块,其中没有内存,而在macos平台上,内存块中有一些内容


如果您需要它,请使用
calloc
,否则对分配的内存块执行
memset
为0的操作。

您能给出一个在Linux上工作但在macOs上不工作的代码示例吗?我不知道如何初始化malloc的结果。在linux上,不需要init_null函数。我的教授告诉我,它确实有效,但在我的mac电脑上,当我键入new->value时,它会打印15780894,例如,然后你在Linux上就幸运了。无法保证从
malloc
返回的内存内容。您应该假设它包含所有平台上的随机值。(即使有时,在某些情况下,您可能无法正确预测,它可能是0)。“在linux上,没有问题。”-这纯粹是偶然的。如果没有
init_null
,您的代码将不会显式初始化
if
的第一个分支中的
指针,这意味着如果没有额外的初始化,Linux上的代码也会被破坏。另外,
root->value=NULL
root->operator=NULL
——这没有任何意义。不要将
NULL
赋值给非指针值。我的教授告诉我它实际上是有效的,我希望教授没有看到你的源代码,然后告诉你。认真地因为如果你的教授确实看到你的源代码使用了未初始化的内存,然后告诉你它工作了,你的教授不理解未定义的行为,没有商业教学C,你真的需要找另一位教授。请注意
malloc
的规范不是这样的“它将内存块中的所有内容都保留在那里。”这是因为malloc为“其值不确定”的对象返回空间。(C 2018 7.22.3.4.2。)这是因为,在现代编译器中,源代码中对
malloc
的调用不一定会转换为CPU指令中的实际调用。C标准允许编译器解释代码并对其进行转换,现代编译器会进行积极的转换以进行优化。当他们看到使用了不确定的值时,它们可能会以意外的方式转换代码。@EricPostpichil我同意你的看法。我没有试图给出详细的答案。更进一步,作者在macos系统上使用的编译器甚至可能会将内存设置为零,这可能是意外/不确定的行为。通常,在linux上,当进程运行时,内存会重置为0这样其他进程的内容就不会泄漏到其他进程中将获得新页面并将归零,但小malloc在开始时始终为0,但在释放一段时间后,它们可能会从同一进程中重新使用内存,并包含垃圾数据。@LtWorf这是一个很好的观点。我希望macOS机器上会出现与本文中可能描述的类似的行为