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

C语言中结构体指针解引用时访问的是哪块内存?

结构体指针解引用的实际行为说明

你的输出和预期不符的核心原因是代码存在未定义行为,和指针解引用的本身逻辑无关。

核心概念梳理

  • 你对a和&(a->val)的理解是完全正确的:a保存的是malloc分配的内存块首地址,C标准明确规定结构体的首地址与其第一个成员的地址完全一致,不存在内存偏移,所以前两个打印值相同是符合预期的。
  • 对结构体指针a做解引用操作(即*a)时,得到的是**a指向的整个struct Node类型的结构体对象本身**,它的类型是struct Node,既不是指针类型,也不是结构体的某个成员,更不是地址值。

你代码的错误点

printf的%p格式符严格要求传入参数必须是void*类型的指针,你传入*a属于参数类型不匹配,是标准明确规定的未定义行为:
你打印出来的第三个值00000000001C0150根本不是什么有效内存地址,只是malloc分配的内存里没有初始化的随机垃圾值——因为你没给a->val赋初值,这块内存里残留的旧数据被printf错误解析成了指针值输出,完全不具备参考意义。

正确的验证方式

你可以用下面的代码验证结构体指针解引用的实际行为:

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

struct Node {
    int val;
};

int main() {
    // 注意纯C环境中struct类型声明变量需要带struct关键字,C++环境可以省略
    struct Node* a = (struct Node*) malloc(sizeof(struct Node));
    a->val = 999; // 给成员赋值,消除未初始化的垃圾值

    printf("malloc分配的内存块首地址(即指针a存储的值): %p\n", (void*)a);
    printf("结构体第一个成员val的地址: %p\n", (void*)&(a->val));
    printf("解引用a后访问结构体val成员的值: %d\n", (*a).val);
    // 验证:结构体指针的->运算符本质就是(*ptr).member的语法糖
    printf("通过a->val访问的值和(*a).val完全一致: %d\n", a->val);

    free(a);
    return 0;
}

运行这段代码你会看到前两个地址完全相同,后两个值完全相同,符合结构体指针的访问逻辑。

补充说明:如果你想拿到结构体首地址对应的第一个成员值,直接用a->val即可;如果你想拿到第一个成员的指针,用&(a->val)或者(int*)a都可以,两者的值完全相等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 18:51:48