Segfault from adding a variable

旧巷老猫 提交于 2019-12-22 18:28:10

问题


I'm admittedly a straight-C newbie, but this has got me stumped. I'm working on a linked list implementation for practice, and I'm getting a segfault by simply adding a variable to the split_node function:

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

struct Node {
    struct Node *child;
    char *content;
};

void print_list(struct Node node);
void split_node(struct Node *node, int position);

int main() {

    struct Node head, second, third;

    head.content = "first";
    second.content = "second";
    third.content = "i'm third";

    head.child = &second;
    second.child = &third;

    print_list(head);
    split_node(&head, 3);
    print_list(head);

    return 0;
}

void print_list(struct Node node) {
    printf("%s\n", node.content);
    if(node.child) print_list(*node.child);
}

    /*
    Split node into two nodes, with the first position characters of the node's content remaining with node, and the remainder being copied to the new node. (It doesn't yet truncate the first node's string, but does do the copy.)
    */
void split_node(struct Node *node, int position) {
    if(position >= strlen((*node).content)) return;
    struct Node newNode;
    newNode.child = (*node).child;
    (*node).child = &newNode;

    int length = (strlen((*node).content) - position);
    newNode.content = malloc(sizeof(char) * (length + 1));
    strncpy(newNode.content, (*node).content + sizeof(char) * position, length);
    newNode.content[length] = '\0';

    //int foo;
}

This code compiles (gcc -Wall -o list list.c) and runs fine:

$ ./list
first
second
i'm third
first
st
second
i'm third

But if I uncomment int foo at the end of split_node, compile and run, I get:

$ ./list
first
second
i'm third
first
st
Segmentation fault

gdb gives me this backtrace:

#0  0x91d6ae70 in strlen ()
#1  0x91dd3126 in puts ()
#2  0x00001f21 in print_list (node={child = 0xbcec815b, content = 0x8b000000 <Address 0x8b000000 out of bounds>}) at list.c:41
#3  0x00001f3c in print_list (node={child = 0x8fe0154b, content = 0x1ff6 "i'm third"}) at list.c:42
#4  0x00001f3c in print_list (node={child = 0xbffff568, content = 0x1fef "second"}) at list.c:42
#5  0x00001f3c in print_list (node={child = 0xbffff570, content = 0x1fe9 "first"}) at list.c:42
#6  0x00001ee0 in main () at list.c:33

Why would adding a variable definition cause a segfault? It appears to be smashing the content pointer of the newly created node. I'm confused; any help?


回答1:


You need to dynamically allocate your nodes (using malloc).

As you have it, your new node is declared on the stack. When the split function returns, that new node is no longer valid memory.

Adding a variable causes a segfault because that variable changes the layout of the stack causing slightly different behavior when the function returns.




回答2:


Try setting the Nodes child property to NULL, C doesn't automagically zero out memory so it looks like your may have garbage in child (or your could use calloc instead of malloc). SoapBox's answer is also correct.




回答3:


Valgrind is a great tool to help find these types of problems. You can just do "valgrind myappname" from the command line and it will give you details on these types of errors.



来源:https://stackoverflow.com/questions/433700/segfault-from-adding-a-variable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!