2016-07-29 74 views
-3

我有一个2D的LinkedList我正在做一个结构:Ç - malloc的崩溃/堆损坏与指针

struct Node 
{ 
    void *data; 
    struct Node *up, *left, *right, *down; 
}; 

因为我已经习惯了Java的,我做这假装是一个构造函数它看起来像:

struct Node* buildNode(void *data) 
{ 
    struct Node *node = malloc(sizeof(struct Node*)); // Program crashes here. 
    node->data = data; 
    node->up = NULL; 
    node->left = NULL; 
    node->right = NULL; 
    node->down = NULL; 
    return node; 
} 

我的程序崩溃当它到达第二段malloc线。如果我从malloc(sizeof(struct Node*))中删除*,它不会崩溃并正常工作。

这是为什么?我的buildNode函数只是返回指向Node的指针,实际上并不返回Node结构本身。我得到的错误与损坏的堆有关,由于我对C有点新,所以我不明白这是什么意思。

谢谢!

回答

9

这条线:

struct Node *node = malloc(sizeof(struct Node*)); 

被分配指针尺寸(4或取决于是否正在构建在32或64位模式的8个字节),并返回一个指向它的指针的存储块。这不是你想要的。

尝试访问返回对象的成员导致未定义的行为(如崩溃),因为您正在访问的内存超出了分配空间的范围。你也可能会沉默地破坏堆,所以后来致电malloc导致崩溃。

鉴于:

struct Node *node = malloc(sizeof(struct Node)); 

被分配的struct Node大小的内存块 - 这是你想要的。另外,您应该在使用它之前检查返回的指针是不是NULL,然后优雅地处理错误。如果分配失败,则返回NULL,例如,如果内存不足。

还要注意C(不像Java)不是垃圾收集语言。您需要确保在您分配的每个指针上调用free,否则在程序终止之前内存不会被释放。

+0

经过大量的学习,我学到了很多关于C的知识,并且我被告知的一件事是您最后的陈述“或者内存不会在程序终止之前发布”。不一定是这样。你能详细说明吗?我看到很多地方说,当程序退出时,你的应用程序占用的空间被释放,不管你是否忘记了。 – Hatefiend

+0

这是正确的。内存不会被释放*直到程序终止*,当OS清理整个过程时。我想你说的和我完全一样。 – Baldrick

+0

哦,对不起,我读'内存将不会被释放,直到'内存将不会被释放' – Hatefiend