C新手在这里,我似乎无法想出这个。所以我开始实现一个链表(只是一些基本的东西,所以我可以把它包围起来),我遇到了麻烦。该程序运行正常,但我无法释放()存储在我的结构中的数据。
这是来源:
#include <stdio.h>
#include <stdlib.h>
struct node {
struct node* next;
void* data;
size_t data_size;
};
typedef struct node node;
node* create_node(void* data, size_t size)
{
node* new_node = (node*)malloc(sizeof(node));
new_node->data = (void*)malloc(size);
new_node->data = data;
new_node->next = NULL;
return new_node;
}
void destroy_node(node** node)
{
if(node != NULL)
{
free((*node)->next);
//this line here causes the error
free((*node)->data);
free(*node);
*node = NULL;
printf("%s\n", "Node destroyed!");
}
}
int main(int argc, char const *argv[])
{
float f = 4.325;
node *n;
n = create_node(&f, sizeof(f));
printf("%f\n", *((float*)n->data));
if (n->next == NULL)
printf("%s\n", "No next!");
destroy_node(&n);
return 0;
}
我在程序输出中收到此消息:
malloc:***对象0x7fff5b4b1cac的错误:释放的指针未分配
我并不完全热衷于如何解决这个问题。
答案 0 :(得分:4)
这是因为当你这样做时:
new_node-&gt; data = data;
您将之前的行替换malloc放置的值。 您需要的是复制数据,请参阅函数memcpy
答案 1 :(得分:3)
node* create_node(void* data, size_t size) ... new_node->data = (void*)malloc(size); new_node->data = data;
这里,(1)你正在丢失malloc
给出的内存,因为第二个赋值会替换存储未知来源指针的地址(2)。
第二个很重要,因为你不能保证data
指向的内存实际上是malloced。在destroy_node
中释放数据成员时,这会导致问题。 (在给定的示例中,正在释放堆栈中的地址)
要修复它,请用
替换第二个作业memcpy (new_node->data, data, size);
destroy_node
函数中还有一个潜在的 double free ,因为next
成员也被释放了。
在链表中,通常一个节点在从列表中取消链接后被释放,因此不应释放下一个节点,因为它仍然可以从被取消链接的节点的前任访问。
答案 2 :(得分:1)
虽然你得到了直接问题的答案,但代码还存在许多其他问题。
struct node {
struct node* next;
void* data;
将*放在类型名称旁边是什么意思?无论如何你都使用它不一致,因为在主节点你有节点* n。
size_t data_size;
};
typedef struct node node;
node* create_node(void* data, size_t size)
{
node* new_node = (node*)malloc(sizeof(node));
你在为什么投射malloc?它是有害的。你应该使用sizeof(* new_node)。如何检查NULL?
new_node->data = (void*)malloc(size);
这更加不必要,因为malloc返回void *所以不需要强制转换。
new_node->data = data;
已经提到的错误。
new_node->next = NULL;
return new_node;
}
void destroy_node(node** node)
{
if(node != NULL)
{
怎么样:
if (node == NULL)
return;
突然间,你摆脱了对整个功能的谴责。
free((*node)->next);
//this line here causes the error
free((*node)->data);
free(*node);
*node = NULL;
printf("%s\n", "Node destroyed!");
%s而不仅仅是printf(“Node destroyed!\ n”)是什么?这条消息无论如何都是坏的,因为它甚至不打印上述节点的地址。