所以我正在做一些链接列表修改,我试图加载一个带有一些数字的列表,然后将其打印出来。以下是我的代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct stack {
int data;
struct stack *next;
}*stack;
stack create_s(void){
stack s = (void*)malloc(sizeof(stack));
s->next = NULL;
return s;
}
void push_s(stack s, int data) {
while (s->next != NULL) {
s = s->next;
}
s->next = (void*)malloc(sizeof(stack));
s=s->next;
s->data = data;
s->next = NULL;
}
void print_s(stack s) {
if (s==NULL) {
return;
}
else {
while (s->next != NULL) {
printf("%d\n",s->data);
s=s->next;
}
}
}
int main (void) {
stack s = create_s();
push_s(s,2);
push_s(s,4);
push_s(s,6);
push_s(s,8);
print_s(s);
return 0;
}
我的输出是:
-1853045587
2
4
6
什么时候应该
2
4
6
8
是否在开头打印我的结构的地址?另外,为什么不打印我的最后一个元素?
由于
答案 0 :(得分:3)
代码包含几个错误,但首先引起注意的是你的内存分配已经明显被打破了
stack s = (void*)malloc(sizeof(stack));
您将stack
定义为指针类型。这意味着sizeof(stack)
计算指针大小,上面的malloc
分配足够的空间来存储单个指针,这对于整个struct stack
对象来说是不够的。 push_s
中也存在相同的内存分配错误。
这是一些建议
不要将指针类型隐藏在typedef名称后面。将您的stack
定义为
typedef struct stack{
int data;
struct stack *next;
} stack;
并在需要指针的地方使用stack *
。即使*
可见,而不是将其隐藏在typedef名称中。这将使您的代码更易于阅读。
不要投射malloc
的结果。无论如何,当void *
已经void *
时,将其转换为sizeof
是什么意思
除非您确实需要,否则不要将sizeof
与类型一起使用。希望malloc
与表达式一起使用。学习使用以下T *p = malloc(sizeof *p);
成语
struct stack *s = malloc(sizeof *s);
或者,在您的情况下
data
这将分配适当大小的内存块。
另外,正如@WhozCraig在评论中指出的那样,列表中的第一个节点显然应该充当“前哨”头节点(具有未定义的data
值)。在您的代码中,您永远不会初始化该头节点中的print_s
值。然而,在data
函数中,您尝试从头节点打印-1853045587
值。难怪你得到垃圾(print_s
)作为输出的第一行。不要打印第一个节点。如果真的应该作为哨兵,请跳过它。
此外,while (s->next != NULL)
中的循环终止条件看起来很奇怪
s->next
为什么要检查NULL
s
而不是检查8
本身?此条件将提前终止循环,而不尝试打印列表中的最后一个节点。这就是您在输出中看不到最后一个元素({{1}})的原因。
答案 1 :(得分:2)
可以通过更改:
来修复给定输出的实际原因s=s->next;
s->data = data;
到
s->data = data;
s=s->next;