Я, по общему признанию, новичок в C, но это поставило меня в тупик. Я работаю над реализацией связанного списка для практики, и я получаю segfault, просто добавляя переменную в функцию split_node:
#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;
}
Этот код компилируется (gcc -Wall -o list list.c) и работает нормально:
$ ./list
first
second
i'm third
first
st
second
i'm third
Но если я раскомментирую int foo
в конце split_node
, скомпилирую и запущу, я получу:
$ ./list
first
second
i'm third
first
st
Segmentation fault
gdb дает мне эту обратную трассировку:
#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
Почему добавление определения переменной может привести к segfault? Похоже, он разбивает указатель содержимого вновь созданного узла. Я запутался; любая помощь?