繁体   English   中英

在结构内部释放指针(指向void *)

[英]Freeing a pointer (to a void*) inside of a struct

在这里是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错误:未分配正在释放的指针

我并不完全热衷于如何解决这个问题。

这是因为当您这样做时:

new_node-> data =数据;

您替换了malloc放在前一行的值。 您需要复制数据,请参见函数memcpy

 node* create_node(void* data, size_t size) ... new_node->data = (void*)malloc(size); new_node->data = data; 

在这里,(1)您正在丢失由malloc给定的malloc因为第二个赋值替换了存储未知来源指针的地址(2)。

第二个很重要,因为您不能保证data所指向的内存实际上是已分配的。 当释放destroy_node的数据成员时,这会导致问题。 (在给定的示例中,正在释放堆栈中的地址)

要解决此问题,请用

memcpy (new_node->data, data, size);

您还将在destroy_node函数中具有潜在的双重释放 ,因为next成员也将被释放。

在链接列表中,通常一个节点在从列表中取消链接后便会被释放,因此不应释放下一个节点,因为它仍可从要取消链接的节点的前身到达。

当您获得了眼前问题的答案时,代码中还有许多其他问题。

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(“节点被破坏了!\\ n”)? 无论如何,此消息很糟糕,因为它甚至没有打印上述节点的地址。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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