[英]Why does passing a struct in this way produce a segfault?
我试图摆脱c的困扰,我不明白为什么这段代码会产生段错误。
// In src/test.c
#include <stdio.h>
typedef struct {
int length;
int *arr[1000];
} Stack;
void push(Stack *stack, int el) {
(*stack->arr)[stack->length++] = el;
}
int pop(Stack *stack) {
return (*stack->arr)[--stack->length];
}
int main(int argc, char* argv[]) {
Stack stack;
push(&stack, 5);
printf("%d\n", pop(&stack));
return 0;
}
然后我编译并运行:
$ gcc src/test.c -o test && ./test
[1] 79484 segmentation fault ./test
你有几个问题。
就像其他人提到的那样,您的int length struct member
永远不会设置为零,因此可以包含任何内容。
您必须将长度设置为0。
其次, int *arr[1000]
是一个integer pointers
数组。 因此,仅将int
分配给特定的数组位置是错误的。
您想要更多类似这样的东西:
// In src/test.c
#include <stdio.h>
typedef struct {
int length;
int arr[1000]; // Code change (create an array of integers)
} Stack;
void push(Stack *stack, int el) {
stack->arr[stack->length++] = el; // Code change (no need for additional
// structure member dereference).
}
int pop(Stack *stack) {
return stack->arr[--stack->length]; // Code change (no need for additional
// structure member dereference).
}
int main(int argc, char* argv[]) {
Stack stack;
stack.length = 0; // Code change (set the starting length value to 0)
push(&stack, 5);
printf("%d\n", pop(&stack));
return 0;
}
在您的结构中,“ length”从未初始化,因此它包含垃圾。 然后请参考:
(*stack->arr)[stack->length++]
它在未定义的位置索引内存。 因此,您需要一些函数,例如“ init_stack()”,以将结构数据成员初始化为众所周知的值(例如零)。
结构中数组的类型错误; 它应该是int arr[1000];
。
如所写,您到处都在使用未初始化的变量。 length
和arr
中的任何指针都未设置为可靠的值(尽管无论如何,指针都应为int
)。 因为堆栈中有指针而不是int
,所以您有一个非常复杂的表达式来访问堆栈( (*stack->arr)[stack->length++]
等),它应该更简单,如本文所述下面的代码。
#include <stdio.h>
typedef struct
{
int length;
int arr[1000];
} Stack;
void push(Stack *stack, int el)
{
stack->arr[stack->length++] = el;
}
int pop(Stack *stack)
{
return stack->arr[--stack->length];
}
int main(void)
{
Stack stack = { 0, { 0 } };
push(&stack, 5);
printf("%d\n", pop(&stack));
return 0;
}
#include <stdio.h>
typedef struct {
int length;
int arr[1000];
} Stack;
void push(Stack *stack, int el) {
(stack->arr)[stack->length++] = el;
}
int pop(Stack *stack) {
return (stack->arr)[--stack->length];
}
int main(int argc, char* argv[]) {
Stack stack;
memset(&stack,0,sizeof(Stack));
push(&stack, 5);
printf("%d\n", pop(&stack));
return 0;
}
经验法则是在访问之前分配内存。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.