【发布时间】:2010-10-09 17:10:58
【问题描述】:
const int z = 420;
const void *v;
v = &z;
printf("\n%d | %d",z,*(int *)v);
//420 | 420
printf("\n%d | %d",*(char *)&z,*(char *)v); //0th-Bit same value
//-92 | -92
printf("\n%d | %d",*((char *)&z+1),*((char *)v+1) ); //1st-Bit same value
//1 | 1
/***********************************************/
*((char *)&z+1) = 21; //I change value for the 1st-Bit
//see v is not touched here.
printf("\n%d | %d -(note)-successfully corrupted (z+1) and change reflected in (v+1)",*((char *)&z+1),*((char *)v+1) );
//21 | 21
//yes change is reflected in v after corruption of z
/****************the problem******************/
printf("\n%d | %d",z,*(int *)v); //but now value of v is courrupt...while that of z is same
//420 | 5540
printf("\n%u | %u",&z,v); //same address different values?
//1310548 | 1310548
/*************additional info*******************/
printf("\n%d | %d",*(&(*(&z+1))-1),*(int *)v);
//5540 | 5540
printf("\n%u | %u",(&(*(&z+1))-1),v);
//1310548 | 1310548
1>
指向“z”的空指针
当取消引用时会给出损坏的值
但是当直接使用 z 时,它会给出原始值。
所以同一个地址有 2 个不同的值
2>
当 z 经受恒等指针变换时
(即递增和递减)
z 现在将输出损坏的值!
但是 z 在进行正常或不进行转换时
like "*(&z)" 仍然会给出原始值。
【问题讨论】:
-
正如 Michael Burr 在回复 your earlier question 时解释的那样,在 C 中修改 const 限定的对象会导致未定义的行为。如果已知对象不会更改,编译器可以执行一些优化,并且您看到的结果很可能是由于这些优化。您可以通过查看编译器生成的代码来找出答案。
-
这是用 void 指针完成的......无论如何,是的,它是未定义的,我明白了......仍然必须有一些编译器专家在那里,谁可以解释为 y 相同的地址包含2 个不同的值...
-
编译器知道
z的值将始终为420,因为您通过const-qualifyingz这么说。我猜当你稍后printf("%d", z)时,编译器会发出将数字420推送到堆栈上的代码,这样它就可以避免对z的内存引用;您可以通过查看编译器为该程序生成的汇编代码来了解是否是这种情况。 -
所以你是在暗示编译器保留 2 个常量副本?
-
我没有暗示什么。我的意思是,如果您真的想知道在这个未定义行为的特定实例中会发生什么,您需要查看编译器生成的程序集。
标签: c pointers segmentation-fault constants