我具有此功能,该功能应该将链结列表中的节点复制(而不是首先复制)
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 ++编译器。
答案 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();