【问题标题】:what is difference between these?这些有什么区别?
【发布时间】:2020-06-28 22:48:51
【问题描述】:

我有这个函数应该复制链表中的一个节点(不是第一个)

struct Node {
    char* data;
    Node* next;
};

void Insert(Node*head, int index, char* data) {//find a is function to find needed position
    Node* temp = find(head, index);
    Node* t = (Node*)malloc(sizeof(Node));
    t->data = (char*)malloc(100);//where the problem is //line 4
    strcpy(t->data, data);
    t->next = temp->next;
    temp->next = t;
}

如果第 4 行在我的代码中,它将运行良好。我读过这个问题:

crash-or-segmentation-fault-when-data-is-copied-scanned-read-to-an-uninitializ

所以我知道指针不能包含任何数据,我不能将数据复制/存储到指针中。所以,如你所见,我先为其分配了内存,然后将数据放入其中,否则我的程序将崩溃。

但是后来我用了这个:t->data = data;,它起作用了,所以我想知道:为什么当我像这样strcpy(t->data, data);使用strcpy时,我需要先为t->data分配内存,否则我的程序会碰撞;但是这个t->data = data; 可以很好地工作,不需要分配内存?

你能给我解释一下吗?

PS:强制转换 malloc 是因为使用了 c++ 编译器。

【问题讨论】:

  • 阿德里安是正确的。此外,您可以使用:t->data = strdup(data); 事实上,100hardwired。如果 data 的字符数超过 100 个,则说明您分配的空间不足。
  • @AdrianMole 抱歉。实际上这是我问的另一个问题,有人告诉我这是错误的。我会编辑它。谢谢。
  • 请贴出所有需要重现的代码。 Node 是什么? data 内存是如何管理的? it worked 究竟是什么? Do not cast result of malloc。请发帖minimal reproducible example
  • @KamilCuk 我添加了它。对不起
  • 通常你需要提供A Minimal, Complete, and Verifiable Example (MCVE) -- 但是这里的分配和其他错误是显而易见的。

标签: c memory memory-management linked-list c-strings


【解决方案1】:

当您使用代码t->data = data 时,您不会 将任何数据复制到您的节点!您所做的只是使节点的data 成员指向 函数的参数也指向的数据 - 所以,如果您稍后更改该数据,那么您将也改变节点的数据。这可能不是你想要的!例如,如果您从“外部”多次调用该函数并使用相同的变量将数据传入,那么您添加的每个节点都会有一个data 成员指向相同一条数据。

如果您确实想将参数中的数据复制到新节点(正如您对 strcpy 的调用所做的那样),那么您必须首先为其分配存储空间,使用(在您的代码)malloc 函数。

但是,正如 cmets 中提到的,strdup 函数在这里更方便:它既分配(确切所需数量的)内存并且一举复制数据:

t->data = strdup(data);

注意:strdup 分配的内存在完成后需要释放(调用free),方法与malloc 分配的内存相同。

【讨论】:

  • 感谢链接,但我使用 c++ 编译器,这就是我转换 malloc 的原因,感谢您的回答,因为我的数据是恒定的,我没有遇到这个问题。现在我知道这种方法有多么错误.
  • @hanie 好的 - 我已经编辑了选角链接,并且我已将您的问题重新标记为 C++。
  • 我正在编写 c 代码(在 c++ 编译器中),但我对 c++ 的知识不够,我的代码是否在 c++ 中?
  • @hanie 它在语法上是正确的(并且可以作为 C++ 代码工作)!然而,自(大约)C++11 以来,有更现代的方法来实现这种事情 - 使用标准模板库(例如 std::string)。
【解决方案2】:

仅当需要引用对象的大小时,才为指针大小分配代码。

// Node* t = (Node*)malloc(sizeof(Node*));
Node* t = (Node*)malloc(sizeof(Node));

更好的是根据引用的对象而不是类型来调整大小。也不需要演员表。

Node* t = malloc(sizeof *t);

字符串分配也很可疑。我希望分配给字符串的大小,而不是固定的 100。

//t->data = (char*)malloc(100);
//strcpy(t->data, data);
size_t len = string(data);
t->data = malloc(len + 1);
strcpy(t->data, data);

健壮的代码会检查分配错误。

Node* t = malloc(sizeof *t);
if (t == NULL) Handle_OutOfMemory();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 2018-08-25
    • 2012-09-27
    • 2011-11-22
    • 2015-08-08
    • 1970-01-01
    相关资源
    最近更新 更多