我的程序有一个有趣的行为。最好先展示代码。
typedef struct PS {
int num;
} PR;
typedef struct PS* PN;
typedef struct {
int num;
int tmp;
} VD;
void F (PN VPtr)
{
register VD* qVPtr = (VD*)VPtr;
// if this is call #2
// qVPtr->tmp already is 8 for VP arg
// qVPtr->tmp already is 16 for VP1 arg
switch(VPtr->num){
case 0:
qVPtr->tmp = 8;
return;
case 1:
qVPtr->tmp = 16;
return;
}
}
int main()
{
PN VP = NULL;
VP = (PN)malloc(sizeof(PR));
VP->num = 0;
F (VP);
PN VP1 = NULL;
VP1 = (PN)malloc(sizeof(PR));
VP1->num = 1;
F (VP1);
F (VP); // call #2 with VP arg
F (VP1); // call #2 with VP1 arg
return 0;
}在main函数中,VP和VP1并不知道qVPtr和tmp字段,但根据F函数中的VPtr参数,可以获得qVPtr->tmp的最后一个值。
你能详细解释一下这种可能性吗?
发布于 2012-11-29 19:29:33
F的行为没有什么奇怪的--如果你告诉它把指针VPtr当作指向VD结构的指针,它就会把内存当作包含VD结构对象的内存,从VPtr开始,尽管那里没有任何VD对象。你的“魔法”出现了,因为PR和VD的结构都以相同大小的整型字段开头。但是下一部分内存是未分配的,这意味着系统可以随心所欲地使用它,当你在那里写的时候,你可以射中你的腿。
发布于 2012-11-29 19:14:18
在函数F中,您写入未分配的内存,这是未定义的行为。不好的和奇怪的事情会发生。
发布于 2012-11-29 19:20:56
您只需写入已分配内存块的末尾。它足够小,因此它命中未分配的虚拟内存区域的机会很低,因此您不会遇到分段错误。但是在像valgrind这样的内存检查器中运行程序,并享受输出:
==624== Invalid write of size 4
==624== at 0x4004E2: F (pr.c:23)
==624== by 0x400529: main (pr.c:37)
==624== Address 0x4c38044 is 0 bytes after a block of size 4 alloc'd
==624== at 0x4A05FDE: malloc (vg_replace_malloc.c:236)
==624== by 0x40050F: main (pr.c:34)
==624==
==624== Invalid write of size 4
==624== at 0x4004EB: F (pr.c:26)
==624== by 0x400555: main (pr.c:43)
==624== Address 0x4c38094 is 0 bytes after a block of size 4 alloc'd
==624== at 0x4A05FDE: malloc (vg_replace_malloc.c:236)
==624== by 0x40053B: main (pr.c:40)
==624==
==624== Invalid write of size 4
==624== at 0x4004E2: F (pr.c:23)
==624== by 0x400561: main (pr.c:45)
==624== Address 0x4c38044 is 0 bytes after a block of size 4 alloc'd
==624== at 0x4A05FDE: malloc (vg_replace_malloc.c:236)
==624== by 0x40050F: main (pr.c:34)
==624==
==624== Invalid write of size 4
==624== at 0x4004EB: F (pr.c:26)
==624== by 0x40056D: main (pr.c:46)
==624== Address 0x4c38094 is 0 bytes after a block of size 4 alloc'd
==624== at 0x4A05FDE: malloc (vg_replace_malloc.c:236)
==624== by 0x40053B: main (pr.c:40)https://stackoverflow.com/questions/13624423
复制相似问题