繁体   English   中英

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

[英]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];

如所写,您到处都在使用未初始化的变量。 lengtharr中的任何指针都未设置为可靠的值(尽管无论如何,指针都应为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM