malloc(sizeof(struct Node))与malloc(sizeof(nodeptr))的不同行为

malloc(sizeof(struct Node))与malloc(sizeof(nodeptr))的不同行为,c,pointers,struct,tree,C,Pointers,Struct,Tree,我试图使用malloc分配内存,我不理解为什么这两个malloc调用会得到不同的结果 下面的一行给出了错误的结果,即使使用gdb我看到了错误的结果 数据正在获得正确的赋值 nodeptr n=malloc(sizeof(nodeptr)) 值头->数据:“!” 值头->均衡->数据:“” 当我这样做时,会得到正确的结果: nodeptr n=malloc(sizeof(struct Node)) 价值头->数据:“w” 价值头->均衡->数据:“X” 我跟帖了,我想我做得对。 在这两种方

我试图使用malloc分配内存,我不理解为什么这两个malloc调用会得到不同的结果

下面的一行给出了错误的结果,即使使用gdb我看到了错误的结果 数据正在获得正确的赋值

  • nodeptr n=malloc(sizeof(nodeptr))

    值头->数据:“!”
    值头->均衡->数据:“”

当我这样做时,会得到正确的结果:

  • nodeptr n=malloc(sizeof(struct Node))

    价值头->数据:“w”
    价值头->均衡->数据:“X”

我跟帖了,我想我做得对。
在这两种方式中,虽然我得到了相同的内存量,但最终我看到的结果不同。

typedef struct Node
{
    struct Node *left, *right, *eq;
    char data;
    bool isEnd;
} *nodeptr;

nodeptr newNode(const char c) {
    nodeptr n = malloc(sizeof(nodeptr));
    // nodeptr n = malloc(sizeof(struct Node));
    n->data = c;
    n->left = NULL;
    n->right = NULL;
    n->left = NULL;
    n->isEnd = false;

    return n;
}

void insert(nodeptr *node, const char *str) {

    if (*node == NULL) {
        *node = newNode(*str);
    }
    nodeptr pCrawl = *node;

    if(pCrawl->data < *str) {
        insert(&pCrawl->right, str);
    } else if (pCrawl->data > *str) {
        insert(&pCrawl->left, str);
    } else {
        if(*(str+1)) {
            insert(&pCrawl->eq, str + 1);
        } else {
            pCrawl->isEnd = true;
        }
    }
}

int main(int argc, char const *argv[])
{

    const char* const strs[5]= {
        "w.",
    };
    nodeptr head = NULL;
    for(int i = 0; i<1; i++) {
        insert(&head, strs[i]);
    }
    return 0;
    printf("Value head->data: \'%c\'\n", head->data);
    printf("Value head->eq->data: \'%c\'\n", head->eq->data);
}
typedef结构节点
{
结构节点*左、*右、*等式;
字符数据;
布尔伊森德;
}*nodeptr;
nodeptr newNode(常量字符c){
nodeptr n=malloc(sizeof(nodeptr));
//nodeptr n=malloc(sizeof(struct Node));
n->data=c;
n->left=NULL;
n->right=NULL;
n->left=NULL;
n->isEnd=false;
返回n;
}
无效插入(nodeptr*node,const char*str){
如果(*节点==NULL){
*node=newNode(*str);
}
nodeptr pCrawl=*节点;
如果(pCrawl->data<*str){
插入(&pCrawl->右侧,str);
}否则如果(pCrawl->data>*str){
插入(&pCrawl->左,str);
}否则{
如果(*(str+1)){
插入(&pCrawl->eq,str+1);
}否则{
pCrawl->isEnd=true;
}
}
}
int main(int argc,char const*argv[]
{
常量字符*常量字符串[5]={
“w.”,
};
nodeptr head=NULL;
对于(int i=0;idata);
printf(“值头->均衡->数据:\'%c\'\n”,头->均衡->数据);
}

两个不同版本分配的内存量不同
sizeof(nodeptr)
指针的大小
sizeof(struct节点)
结构的大小。这些东西不一样,大小也不一样。在我的计算机上,这些值是832

您要使用:

nodeptr n = malloc(sizeof(struct Node));
或许:

nodeptr n = malloc(sizeof(*n)); // size of the type that n points too
sizeof(nodeptr)
==
sizeof(struct Node*)
!=
sizeof(结构节点)
=
sizeof(*nodeptr)

  • sizeof(nodeptr)
    始终是指针的大小(如64位CPU上的8个字节)
  • sizeof(结构节点)
    指的是结构内容
  • sizeof(*nodeptr)
    相当于
    sizeof(struct Node)
    ,其中包含额外的解引用操作符

它看起来“工作”(而不是segfault)的原因是
malloc
从更大的堆内存块进行子分配。但是,代码写入超出了请求分配的范围,这最终可能会导致堆损坏或在某个点出现segfaults。

请注意,
newNode()
函数不会初始化结构的
eq
成员。应该是,<代码>nodeptr n=malloc(sizeof(nodeptr))这将为指针分配足够的内存。(4或8个字节,取决于底层硬件和某些编译器选项),因此将任何内容作为该指针的偏移量写入都是未定义的行为。OT:不要通过
typedef
s隐藏指针