修改引用指针会改变原指针地址吗?为何未操作s->name其值却变化?
问题解答
一、修改引用指针是否会改变原指针地址?
- 不会。当你创建新指针(比如
char* ptr = s->name;),这个新指针只是复制了原指针的地址值,是完全独立的变量。修改新指针的指向(比如ptr +=3)只会改变新指针自身存储的地址,不会影响原指针s->name的地址值——除非你通过新指针直接修改原指针所在的内存(这正是第二个问题的核心原因)。
二、为什么s->name的值在操作后莫名改变?
这是典型的内存越界覆盖问题,具体分析如下:
1. 结构体与内存分配的关键矛盾
student结构体的实际大小:meta_data包含3个int(共12字节),加上char* name(32位系统下占4字节),整个结构体共占16字节。- 你通过
malloc(sizeof(meta_data) + 10)仅分配了22字节内存,虽然能容纳student结构体,但这行代码犯了致命错误:
这行代码将s->name = (char *)s + sizeof(meta_data);s->name赋值为(char*)s + 12,而这个地址正好是student结构体中name成员自己的起始地址(因为mt_data占12字节,name成员从偏移12字节处开始)。也就是说,s->name这个指针变量,现在存储的是它自己的内存地址。
2. 内存覆盖的具体过程
char* ptr = s->name;:ptr此时等于(char*)s + 12,也就是name成员的地址。ptr +=3;:ptr变为(char*)s + 15,这个地址是name成员的第4个字节(name是4字节指针,占12-15字节区间)。memcpy(ptr, "sri",3);:从(char*)s +15开始写入3字节数据,直接覆盖了:(char*)s +15:name成员的第4字节(char*)s +16、(char*)s +17:结构体后续的内存空间
这就直接篡改了name成员本身的存储值,导致后续打印s->name时出现异常。
3. 额外问题:指针打印格式错误
你用%d打印指针地址是错误的,%d用于打印int类型,指针应该使用%p格式符,否则在64位系统中会因类型截断导致输出错误。
内容的提问来源于stack exchange,提问作者SRIKANTH
相关产品推荐
相关产品推荐

