再次修改常量..使用 void 指针
可能的重复:
修改了 c 中的常量
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”的 void 指针
会给出损坏的值,
但当直接使用 z 时,它会给出原始值。
所以同一个地址持有2个不同的值
2>
当 z 受到恒等指针变换
(即递增和递减)
时, z 现在将输出损坏的值!
但 z 当进行正常或无转换
(如“*(&z)
”)时仍将给出原始值。
Possible Duplicate:
Modified a constant in c
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>
void pointer pointing to "z"
when dereferenced gives corrupted value
but when z is used directly it gives original value.
so same address is holding 2 different values
2>
when z is subjected to an identity pointer transformation
(i.e. increment and decrement back)
z will now output the corrupted value!
but z when subjected to normal or no transformations
like "*(&z)
" will still give the original value.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您确实想防止数据被修改,请使用操作系统声明其内存页不可修改。
C和C++中的const是一种概念上的安全机制和弱验证工具,而不是一种安全措施。它为遵循一定规则的程序员提供了保证。如果违反规则,则没有任何保证。 (取决于严重程度,不能保证它不会崩溃。您的程序可以崩溃或为“常量”提供不一致的值。)
哦,您真正的问题是地址处如何“存在”两个不同的值。答案是,如果编译器确定它知道您正在引用常量,它不会查看地址,而只是给出值。毕竟,这就是你应该告诉它没问题的。
If you really want to prevent data from being modified, use your operating system to declare its memory page non-modifiable.
const
in C and C++ is a conceptual safety mechanism and a weak verification tool, not a security measure. It provides guarantees to programmers who follow certain rules. If the rules are broken, no guarantees. (Depending how severely, no guarantee it doesn't crash. Your program is allowed to crash or provide inconsistent values for the "constant.")Oh, your real question is how there can "be" two different values at the address. The answer is that if the compiler decides it knows you're referring to the constant, it won't look at the address and just gives the value instead. After all, that's what you were supposedly telling it is OK.
不要再问这个问题了;-)
如果有帮助,您可以假设编译器已经采用了这样的代码:
并将其替换为:
这不能保证,您不能依赖它,但这是编译器所做的事情,并且它会解释你所看到的。
您还获取了
z
的地址,但编译器不会/不一定跟踪该指针的使用,并以相同的方式替换通过它的所有访问。这比仅仅识别符号z
引用 const 对象要困难得多。因此,当您无效地修改该 const 对象时,未定义行为的表现方式之一就是您所看到的不一致。如果您想知道您的编译器实际上做了什么,并且您不遵循 James 的建议,那么您就不走运了。这里没有人确切地知道你的编译器做了什么。甚至没有人知道您使用的是什么编译器。不同的编译器做不同的事情。
Stop asking this question ;-)
If it helps, you can assume that the compiler has taken code like this:
And replaced it with:
That's not guaranteed, you can't rely on it, but it's the kind of thing compilers do, and it would account for what you're seeing.
You also take the address of
z
, but the compiler won't/can't necessarily track the use of that pointer, and replace all accesses through it in the same way. That's a much harder job than just recognising that the symbolz
refers to a const object. So when you invalidly modified that const object, one of the ways in which undefined behavior has manifested is the inconsistencies you're seeing.If you want to know what your compiler has actually done, and you won't follow James' advice, then you're out of luck. Nobody here knows for sure exactly what your compiler has done. Nobody even knows what compiler you're using. Different compilers do different things.