C 指针操作中未按预期打印结构变量的值
在上面的程序中,为什么我得到“0”并且mycode函数中没有显示数据,它应该是“10”,并且应该打印“sample”,程序有什么问题?据我所知,当我们进行清理时,我没有作为引用传递,所以它不应该影响结构的本地副本。C 指针操作中未按预期打印结构变量的值,c,pointers,malloc,structure,C,Pointers,Malloc,Structure,在上面的程序中,为什么我得到“0”并且mycode函数中没有显示数据,它应该是“10”,并且应该打印“sample”,程序有什么问题?据我所知,当我们进行清理时,我没有作为引用传递,所以它不应该影响结构的本地副本。 请澄清我的疑问我认为您的问题在于清理(p) 在打印数据之前不应该这样做 据我所知,当我们进行清理时,我不会作为引用传递,所以它不应该影响结构的本地副本。请澄清我的疑问 你部分是对的。 在“清理”中,您只有一份p。将NULL赋值给它不会改变任何东西 但是您将globalp的值传递给函数
请澄清我的疑问我认为您的问题在于清理(p) 在打印数据之前不应该这样做 据我所知,当我们进行清理时,我不会作为引用传递,所以它不应该影响结构的本地副本。请澄清我的疑问 你部分是对的。 在“清理”中,您只有一份
p
。将NULL
赋值给它不会改变任何东西
但是您将globalp
的值传递给函数,然后调用free
。
这不会改变p
,但会释放指向的内存
调用cleanup
后,不允许再次访问该内存位置
你期望得到什么
Hello, World!
p->a - 10
p.b - sample
p->a - 10
p.b - sample appenddata
p->a - 0
p.b -
基于错误的假设。
您可以得到任何值,因为这是未定义的bahaviour
顺便说一句:
如果内存不是无效的,您将得到
10
sample
这是出于同样的原因
在
appenddata
中,您不会更改p
,但会更改p->b
,它在您离开函数后仍然存在。为避免出现与free
相关的警告,请将添加到源代码,在清理过程中,您会清理结构数据并取消引用本地指针而不是主指针。因此,主指针变为悬挂指针
在演示中添加了一些printf:
10
sample appenddata
于是试图打印出指针悬空指向的垃圾
为了避免这种情况,你可以采取任何一种方法
将清除函数替换为宏
Hello, World!
p->a - 10
p.b - sample
p->a - 10
p.b - sample appenddata
Pointer Address before cleanup : 0x14a5020
Pointer Address before free : 0x14a5020
Pointer Address after free : (nil)
Pointer Address after cleanup : 0x14a5020
p->a 1- 0
p.b 2-
或从清除函数返回指针
#define cleanup(p) free(p); p=NULL
您的程序有两个未定义的行为
第一个未定义的行为:
在struct type
中,成员b
作为10
字符的数组:
MyType* cleanup(MyType* pointer);
....................
/* set the values for p and do some stuff with it */
p = cleanup(p);
.......................
MyType* cleanup(MyType* pointer) {
free(pointer);
pointer = NULL;
return pointer;
}
在函数appenddata()
中,将长度超过10个字符的字符串复制到b
:
char b[10];
访问超出边界的数组是未定义的行为
要解决此问题,请增加数组b
,如b[50],并使用strncpy
,这样可以控制要复制到目标的字符数。使用strncpy之前,请仔细阅读它
第二个未定义的行为:
当您释放一个动态分配的内存块时,它的生存期就结束了
来自C标准#6.2.4p2
对象的生存期是程序执行期间保证为其保留存储的部分。对象存在,具有恒定地址33),并在其整个生存期内保留其最后存储的值。34)如果对象在其生存期之外被引用,则行为未定义。当指针指向(或刚刚经过)的对象到达其生命周期结束时,指针的值变得不确定。
[我的重点]
在这里,您将在释放后访问p
:
strcpy(p->b, "sample appenddata");
^^^^^^^^^^^^^^^^^
if(p!=NULL)
{
printf(“p->a-%d\n”,p->a);b);您正在跟踪p
和#include
。打开警告。即使在解决Keine注意到的问题后,pointer=NULL;
在cleanup
中是无意义的。所做的只是将本地指针变量设置为NULL
,调用方提供的参数将保持不变(虽然它将保存一个现在悬空的无效指针值)。即使我在mycode函数中获取“MyType*p”的本地副本,我也会得到相同的结果!!!#Gerhardhhi如果您的p
是全局p
的副本,那么它将指向相同的内存并导致完全相同的问题。
strcpy(p->b, "sample appenddata");
^^^^^^^^^^^^^^^^^
if(p != NULL)
{
printf("p->a - %d\n",p->a); << Why value I am getting is '0' here and
printf("p.b - %s\n",p->b); << No value is printed here
}