如何解决将struct指针元素复制到指针似乎损坏了它
|| 我仍在学习C,并且在某些时候我必须对指针有误解。 我的印象是,以下几行会将“ 0”存储的内存地址复制到“ 1”。它们都是“ 2”指针,所以我看不到问题。struct list_elt * temp;
temp = l->first;
运行示例代码给我一个无限循环:
user@machine:~$ gcc question.c
user@machine:~$ ./a.out | head
append(): l->first->val: 30,l->first->next == NULL: 1
main() : l->first->val: 30,l->first->next == NULL: 1
print() : l->first->val: 30,l->first->next == NULL: 1
print() : temp->val: 30,temp->next == NULL: 0
print() : temp->val: 30,temp->next == NULL: 0
这是5英镑。很抱歉,我无法进一步缩小范围,每次执行此问题时,问题似乎都消失了。
#include <stdio.h>
#include <stdlib.h>
struct list_elt {
int val;
struct list_elt * next;
};
struct linked_list {
struct list_elt* first;
};
void print(const struct linked_list * l);
struct linked_list* new_list(void);
void append(struct linked_list* l,int value);
main()
{
struct linked_list * l;
l = new_list();
append(l,30);
printf(\"main() : l->first->val: %d,l->first->next == NULL: %d\\n\",l->first->val,l->first->next == NULL);
print(l);
}
struct linked_list* new_list()
{
struct linked_list* l;
l = (struct linked_list*) malloc(sizeof(struct linked_list));
l->first = NULL;
return l;
}
void append(struct linked_list* l,int value)
{
struct list_elt el = {0,NULL};
el.val = value;
el.next = NULL;
if (l->first == NULL) {
l->first = (struct list_elt*) ⪙
printf(\"append(): l->first->val: %d,l->first->next == NULL);
} else {
printf(\"append(): Unimplemented\\n\");
}
}
void print(const struct linked_list * l)
{
printf(\"print() : l->first->val: %d,l->first->next == NULL);
struct list_elt * temp;
temp = l->first;
while (temp != NULL) {
printf(\"print() : temp->val: %d,temp->next == NULL: %d\\n\",temp->val,temp->next == NULL);
temp = temp->next;
}
printf(\"\\n\");
}
谢谢。
解决方法
您的
append
功能错误。它在堆栈上分配el
,并使用列表中的指针。这样做的问题是,在append
(在本例中为after10)之后调用另一个函数时,内存将被垃圾覆盖。相反,使用malloc进行分配,如下所示:
int append(struct linked_list* l,int value)
{
struct list_elt *el = malloc(sizeof(struct list_elt));
if (el)
{
el->val = value;
el->next = NULL;
if (l->first == NULL) {
l->first = el;
printf(\"append(): l->first->val: %d,l->first->next == NULL: %d\\n\",l->first->val,l->first->next == NULL);
} else {
printf(\"append(): Unimplemented\\n\");
}
return 0;
}
else
{
return 1;
}
}
, 您要在append
函数的堆栈上分配list_elt。一旦函数返回,此指针将无效,并且不应再对其进行引用。
您应该用malloc
分配元素。
, 在append()
中,将you0ѭ设置为本地堆栈变量local8ѭ的地址。但是,一旦append()
返回,el
就超出范围,因此此后任何取消引用l->first
的尝试都是未定义的行为。
, (下面是一个非常简单的解释,如此简单,以至于可以说是不精确的。为简单起见,我可以通过在C语言中查询堆栈和堆来了解更多信息)。
基本上有两种创建事物并将它们存储在内存中的方法:使用堆栈,或向操作系统请求内存。
堆栈是临时内存,用于跟踪当前执行上下文。每次调用函数时,堆栈的一个扇区都用于存储所有局部变量。这就是您在ѭ14中所做的事情:使用堆栈中的临时内存存储新的列表节点。
从函数返回时,堆栈中的任何内容(任何局部变量)都被认为在时间和空间上丢失了,因为当前的执行上下文不再相关,并且此内存被其他上下文重用(例如,下一个函数调用) 。这是不可避免的,这是如何管理此内存的结果,它发生在您无法直接用C访问的范围内(或者,您不应对此感到困惑)。
当您想在本地范围之外存储某些东西时,这些东西通常与您的程序有关,而不仅仅是与当前执行上下文有关,那么您必须向操作系统请求额外的内存,而该临时堆栈不会这样做。有许多功能-查看最简单的simple21ѭ。
希望能有所帮助。干杯!
, 另外,您的元素是在堆栈上创建的,并在以后引用:这是错误的。当函数退出时,el
变量不再存在。您需要分配您的list_elt。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。