将数据复制到 c 中的节点值会导致段错误,但 malloc 将其删除

标签 c segmentation-fault malloc treenode

我有以下用于在 bst 中插入节点的程序

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


struct node {
    int key;
    struct node * left;
    struct node * right;
};

struct node * insert(struct node *,int);

int main( int argc, const char *argv[]){
    struct node *root= malloc(sizeof(struct node ));

    int x;

    if(root==NULL){
        printf("mem error"); 
        return;
    }
    root=NULL;


    while(1){
        fprintf(stdout, "Enter the value of data\n" );
        fscanf(stdin,"%d",&x);
        root=insert(root,x);

    }


}

struct node * insert(struct node * root, int data ){

    if(root==NULL){
       struct node *root= malloc(sizeof(struct node ));
       root->key = data;
       printf("hiii\n");
       root->left = NULL;
       root->right = NULL;
       return root;
    }else{
       if(root->key >= data){
          root->left = insert(root->left,data);
       }else if(root->key <= data){
          root->right = insert(root->right,data);
       }
       return root;
    }
}

它运行良好..但是如果我注释插入函数中的malloc行..它在获取第一个值后会给我一个段错误。这是怎么回事??

最佳答案

您不能在插入函数中注释 malloc-line。 malloc() 的用途是动态分配新内存,以便将新节点插入到链表中。

阅读:void* malloc (size_t size);

Allocate memory block
Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.

所以假设如果您在 insert() 中注释/删除 malloc 行(阅读注释):

//struct node *root= malloc(sizeof(struct node ));
root->key = data;  // here illegal operation

root->left = NULL;  //   here illegal operation
root->right = NULL;  //  here illegal operation

那么root值将是垃圾,您将访问进程未分配的垃圾地址并执行读/写操作 - 内存非法操作。

您的代码将编译,因为从语法角度来看,代码是正确的,但在运行时操作系统将检测到非法内存访问并可以终止您的代码。 (有趣的是:当操作系统检测到进程对内存权限的侵犯时,对有效内存的无效访问会给出:SIGSEGV,对无效地址的访问会给出:SIGBUS)。 --实际上这会导致未定义的行为。在最坏的情况下,您的程序可能看起来执行时没有任何失败,从而产生垃圾结果。

it gives me a segmentation fault after taking the first value. what is going on here?

正如我上面所解释的,删除 malloc() 会使您的程序以未定义的方式运行(阅读: Undefined behaviour )。如果程序以未定义的行为运行,您可以猜测会发生什么,在最坏的情况下,您的程序可能会执行而没有任何失败,或者可能会部分运行(这就是您所观察到的)。事情是,当操作系统检测到非法内存访问并发送信号来终止进程时。 (可能是root的前五个随机垃圾值指向与我们的程序关联的内存,并且根据操作系统对该内存的访问不是非法操作符 - 而的第五次随机值root 是不属于操作系统检测到的进程和对该内存的读/写操作的内存,因此您的代码最终因段错误而终止)。

关于将数据复制到 c 中的节点值会导致段错误,但 malloc 将其删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17886228/

相关文章:

使用 OpenSSL 为 DES 编译 C 程序

c - 为什么这个函数永远不会返回?是段错误吗?

c++ - 供应商是否将 new 和 malloc 实现为小对象分配器?

c - 打印内存地址,映射

c - C 中的连接超时

c - 为什么我可以在函数内而不是在 main 中递增 char 数组位置

c - 导致段错误的 int 指针的动态数组

C:有时会出现段错误?

c - `malloc()` 刚刚分配的内存内容是什么?

c - getchar() 如何在 While 循环中工作?