为什么以这种方式传递结构会产生段错误?

时间:2014-02-08 16:53:11

标签: c memory segmentation-fault

我正试图了解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

4 个答案:

答案 0 :(得分:4)

你有一些问题。

与其他人提到的一样,您的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;
}

答案 1 :(得分:1)

在你的结构中,“length”永远不会被初始化,因此它包含垃圾。你什么时候参考:

(*stack->arr)[stack->length++]

它是在未定义的位置索引内存。所以,你需要一些函数,比如“init_stack()”来将结构数据成员初始化为众所周知的值(如零)。

答案 2 :(得分:1)

结构中数组的类型错误;它应该是int arr[1000];

如上所述,你在整个地方使用未初始化的变量; length中的arr和任何指针都没有设置为可靠的(尽管指针应该是普通的int)。因为你的堆栈中有指针而不是int,所以你有一个非常复杂的表达式来访问堆栈((*stack->arr)[stack->length++]等),这应该更简单,就像下面的重写代码一样。 / p>

#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;
}

答案 3 :(得分: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;
}

拇指规则在访问之前分配内存。