You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何malloc分配8字节指针内存却能存储16字节Node结构体?

为啥malloc了指针大小的内存,却能存下更大的结构体?

你犯了一个常见错误:用sizeof(struct Node *)(8字节)代替了sizeof(struct Node)(16字节)来分配内存,但代码居然没立刻崩,还能正常写入结构体的两个字段——这其实是未定义行为的典型表现,只是运气好没触发问题而已。

先看你的代码问题

错误的内存分配代码:

struct Node
{
  int data;
  struct Node *next;
};

struct Node *GetNode(int data)
{
  // 这里只分配了指针大小的内存(8字节),但结构体需要16字节
  struct Node *node = (struct Node *)malloc(sizeof(struct Node *));
  node->data = data; // 越界写内存
  node->next = NULL; // 继续越界
  return node;
}

你已经通过代码确认了大小差异:

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

struct Node
{
  int data;
  struct Node *next;
};

int main(){
  int i = sizeof(struct Node);
  int j = sizeof(struct Node *);
  printf("%d,%d", i, j);
  return 0;
}

输出:16,8

为啥代码暂时没崩?

这不是你的代码“没问题”,只是以下几个因素让错误没立刻暴露:

  • malloc的额外分配机制:malloc为了内存对齐和管理堆结构,通常会分配比你请求更大的块。比如你要8字节,它可能实际给16字节(刚好匹配你的结构体大小),但这是malloc实现的细节,不同平台、不同版本的C库都可能不一样,绝对不能依赖。
  • 内存页的保护机制:操作系统是以内存页(一般4KB)为单位管理内存的。你越界写的8字节,只要还在当前进程的同一个内存页里,操作系统不会立刻拦你。但你已经在破坏堆的元数据或者其他未被使用的内存了。
  • 暂时没被占用的空闲内存:你越界写入的区域,刚好还没被其他malloc请求占用。一旦后续有其他内存分配/释放操作,就会破坏堆的结构,导致程序崩溃、数据乱掉,甚至出现诡异的逻辑错误。

这问题有多严重?

未定义行为的可怕之处在于:它可能在测试时完全正常,上线后随机崩溃;可能悄悄篡改其他变量的值,让你查半天找不到bug;甚至可能被利用成安全漏洞。

正确的写法

永远确保分配足够的内存,而且推荐用sizeof(*node)这种写法,避免类型写错:

struct Node *node = malloc(sizeof(*node));

这样就算以后把struct Node改成别的类型,这段代码也不用改,更安全。

内容的提问来源于stack exchange,提问作者Areeb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 02:50:51