我试图在ansi c(c89)中编写最简单的通用链表。
此处的代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct node {
struct node *previous;
struct node *next;
void *value;
};
struct node*
allocate_node(void);
void
free_node(struct node *freeable_node);
void
init_node(struct node *initializable_node);
void
print_node(struct node *printable_node);
struct node*
allocate_node(void)
{
struct node *allocatable_node =
(struct node*) calloc(1, sizeof(struct node));
allocatable_node -> previous = NULL;
allocatable_node -> next = NULL;
return allocatable_node;
}
void
free_node(struct node *freeable_node)
{
free(freeable_node -> previous);
free(freeable_node -> next);
free(freeable_node -> value);
free(freeable_node);
}
void
init_node(struct node *initializable_node)
{
int *initializable_value = (int*) (initializable_node -> value);
initializable_value = calloc(1, sizeof(int*));
*initializable_value = rand() % 100;
}
void
print_node(struct node *printable_node)
{
printf("%d\n", *((int*) (printable_node -> value)));
}
int
main(void)
{
struct node *demo_list = NULL;
srand((unsigned int) time(NULL));
demo_list = allocate_node();
init_node(demo_list);
print_node(demo_list);
free(demo_list);
return 0;
}
通过clang
,它成功编译,但在运行打印segfault
后。
valgrind
输出:
$ valgrind ./build/app
==23061== Memcheck, a memory error detector
==23061== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==23061== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==23061== Command: ./build/app
==23061==
==23061== Invalid read of size 4
==23061== at 0x4007AE: print_node (app.c:56)
==23061== by 0x400813: main (app.c:67)
==23061== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==23061==
==23061==
==23061== Process terminating with default action of signal 11 (SIGSEGV)
==23061== Access not within mapped region at address 0x0
==23061== at 0x4007AE: print_node (app.c:56)
==23061== by 0x400813: main (app.c:67)
==23061== If you believe this happened as a result of a stack
==23061== overflow in your program's main thread (unlikely but
==23061== possible), you can try to increase the size of the
==23061== main thread stack using the --main-stacksize= flag.
==23061== The main thread stack size used in this run was 8388608.
==23061==
==23061== HEAP SUMMARY:
==23061== in use at exit: 32 bytes in 2 blocks
==23061== total heap usage: 2 allocs, 0 frees, 32 bytes allocated
==23061==
==23061== LEAK SUMMARY:
==23061== definitely lost: 8 bytes in 1 blocks
==23061== indirectly lost: 0 bytes in 0 blocks
==23061== possibly lost: 0 bytes in 0 blocks
==23061== still reachable: 24 bytes in 1 blocks
==23061== suppressed: 0 bytes in 0 blocks
==23061== Rerun with --leak-check=full to see details of leaked memory
==23061==
==23061== For counts of detected and suppressed errors, rerun with: -v
==23061== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault
任何想法如何解决?
答案 0 :(得分:2)
问题很简单,你在init_node
函数中缺少一行。
void
init_node(struct node *initializable_node)
{
int *initializable_value = (int*) (initializable_node -> value);
initializable_value = calloc(1, sizeof(int*));
*initializable_value = rand() % 100;
//This line puts the variable you just created in the structure
initializable_node->value=initializable_value;
}
顺便在main
函数中,我认为您打算使用free_node(demo_list);
代替free(demo_list);
如果您需要更多帮助,请随时提问!
编辑:实现了init_node
函数的第一行,因为您将int
指针指定为NULL值。
相反,请执行此操作:
void
init_node(struct node *initializable_node)
{
int *initializable_value = calloc(1, sizeof(int*));
*initializable_value = rand() % 100;
//This line puts the variable you just created in the structure
initializable_node->value=initializable_value;
}
答案 1 :(得分:1)
free(freeable_node -> value);
此void * value
永远不会初始化。所以value
默认会有垃圾值,你试图释放那个记忆。