这些之间有什么区别?

时间:2020-03-17 20:02:07

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

我具有此功能,该功能应该将链结列表中的节点复制(而不是首先复制)

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使用strcpy(t->data, data);时,我需要为{{1 }},否则我的程序将崩溃;但这t->data可以很好地工作,而无需分配内存吗?

你能跟我解释一下吗?

PS:广播malloc是因为使用c ++编译器。

2 个答案:

答案 0 :(得分:3)

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

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

但是,如评论中所述,strdup函数在这里更加方便:这既分配了(精确所需的)内存,又一次复制了数据:

t->data = strdup(data);

注意:完成后,strdup分配的内存需要释放(通过调用free),其释放方式与{{1}分配的内存相同}。

答案 1 :(得分: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();