结构的 malloc 上的分段错误(核心转储)

Lor*_*tti 0 c

我有一个由线路引起的分段错误错误

*head = malloc(sizeof(struct node)+1);'
Run Code Online (Sandbox Code Playgroud)

我很确定我在其他情况下以相同的方式使用了构造节点和 malloc,一切都工作正常。程序在此处打印1,然后发生核心转储。

这是我的代码:

struct node {
    //int val ;
    struct node * next;
    unsigned char string[];
 } ;

void init_list(struct node ** head) {
    
    printf("here1 \n");
    fflush(stdout);
    *head = malloc(sizeof(struct node)+1);
    printf("here2\n"); 
    fflush(stdout); 
    if(!(*head)){
    
            printf("error malloc \n");
            fflush(stdout);
            return ;
    }
    //(*head) -> val = -1; 
    (*head) -> next = NULL;
    ((*head) -> string)[0]= '\0'; 
    return ;

  }

  int main(void) {
     struct node ** head;
     init_list(head) ;
     printf("hereee\n");
     fflush(stdout) ;
     fini_list(head);
     return 1;
  }
Run Code Online (Sandbox Code Playgroud)

这是 Valgrind 返回给我的:

==6688== Memcheck, a memory error detector
==6688== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6688== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==6688== Command: ./ex3
==6688== 
 heree 
==6688== Invalid write of size 8
==6688==    at 0x109267: init_list (ex3.c:43)
==6688==    by 0x1092E9: main (ex3.c:66)
==6688==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==6688== 
==6688== 
==6688== Process terminating with default action of signal 11 (SIGSEGV)
==6688==  Access not within mapped region at address 0x0
==6688==    at 0x109267: init_list (ex3.c:43)
==6688==    by 0x1092E9: main (ex3.c:66)
==6688==  If you believe this happened as a result of a stack
==6688==  overflow in your program's main thread (unlikely but
==6688==  possible), you can try to increase the size of the  
==6688==  main thread stack using the --main-stacksize= flag.
==6688==  The main thread stack size used in this run was 8388608  .
==6688== 
==6688== HEAP SUMMARY:
==6688==     in use at exit: 9 bytes in 1 blocks
==6688==   total heap usage: 2 allocs, 1 frees, 1,033 bytes allocated
==6688== 
==6688== LEAK SUMMARY: 
==6688==    definitely lost: 9 bytes in 1 blocks
==6688==    indirectly lost: 0 bytes in 0 blocks
==6688==      possibly lost: 0 bytes in 0 blocks
==6688==    still reachable: 0 bytes in 0 blocks
==6688==         suppressed: 0 bytes in 0 blocks
==6688== Rerun with --leak-check=full to see details of leaked memory
==6688== 
==6688== For lists of detected and suppressed errors, rerun with: -s
==6688== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)

我真正无法理解的是,我使用了相同的构造其他程序,并且所有情况都工作正常。

那么,前面的情况会发生什么?

Ger*_*rdh 5

您将未初始化的指针传递给您的函数:

int main(void) {
     struct node ** head;
     init_list(head) ;
Run Code Online (Sandbox Code Playgroud)

因此,head不包含有效地址并取消引用它会*head = ...导致崩溃。malloc完全没有关系。

这不是该函数应该使用的方式。您不能通过这种方式将新指针传递给调用者。

试试这个:

int main(void) {
     struct node *head = NULL;
     init_list(&head) ;
Run Code Online (Sandbox Code Playgroud)