繁体   English   中英

为什么会出现细分错误?

[英]Why am I getting Segmentation fault?

我正在尝试学习如何在C中使用结构和链接列表,但我真的不明白为什么以下代码会给我带来Segmentation错误:

我有3个名为list.h,operations.c和main.c的文件 在文件list.h中

#include <stdio.h>
#include <stdlib.h>

typedef char DATA;

struct linked_list {
    DATA                   d;
    struct linked_list *next;
};

typedef struct linked_list ELEMENT;
typedef ELEMENT              *LINK;

LINK string_to_list(char s[]);
void print_list(LINK);

文件operation.c

#include "list.h"

LINK string_to_list(char s[]){
    LINK head = NULL;

    if (s[0]) {
        ELEMENT c = {s[0], NULL};
        c.next = string_to_list(s+1);
        head = &c;
    }

    return head;
}

void print_list(LINK head) {
    if(head != NULL){
        putchar(head -> d);
        print_list(head -> next);
    } else {
        putchar('\n');
    }
}

文件main.c

#include "list.h"

int main(void) {
    LINK head = string_to_list("wtf");
    print_list(head);
    return 0;
}
if (s[0]) {
    ELEMENT c = {s[0], NULL};        // Allocate space for struct on the stack
    c.next = string_to_list(s+1);
    head = &c;                       // Save the address to head
}  // <-- poof, c goes out of scope and is deallocated from the stack

return head; // <-- return address of deallocated object

string_to_list您将在if语句中使用局部变量的地址( 在大多数现代实现中,该地址存储在堆栈中 ):

head = &c;

然后在此处返回该地址:

return head;

if语句结束后,变量c将不再存在,这是未定义的行为 C99标准草案6.2.4“对象的存储期限”2段说:

[...]如果在生命周期之外引用对象,则行为是不确定的。[...]

if (s[0]) {
--->    ELEMENT c = {s[0], NULL};
    c.next = string_to_list(s+1);
    head = &c;
}

return head;

是本地内存。 离开函数(甚至代码块)后,该内存将被释放并且不再有效。 您需要对其进行malloc()或传递一些内存,以使该函数可以在该函数之外使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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