再次修改常量..使用 void 指针

发布于 2024-09-26 14:55:54 字数 1551 浏览 4 评论 0原文

可能的重复:
修改了 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

殊姿 2024-10-03 14:55:54

如果您确实想防止数据被修改,请使用操作系统声明其内存页不可修改。

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.

‘画卷フ 2024-10-03 14:55:54

不要再问这个问题了;-)

如果有帮助,您可以假设编译器已经采用了这样的代码:

const int z = 420;
...
printf("%d\n", z);

并将其替换为:

const int z = 420;
...
printf("%d\n", 420);

这不能保证,您不能依赖它,但这是编译器所做的事情,并且它会解释你所看到的。

您还获取了 z 的地址,但编译器不会/不一定跟踪该指针的使用,并以相同的方式替换通过它的所有访问。这比仅仅识别符号 z 引用 const 对象要困难得多。因此,当您无效地修改该 const 对象时,未定义行为的表现方式之一就是您所看到的不一致。

如果您想知道您的编译器实际上做了什么,并且您不遵循 James 的建议,那么您就不走运了。这里没有人确切地知道你的编译器做了什么。甚至没有人知道您使用的是什么编译器。不同的编译器做不同的事情。

Stop asking this question ;-)

If it helps, you can assume that the compiler has taken code like this:

const int z = 420;
...
printf("%d\n", z);

And replaced it with:

const int z = 420;
...
printf("%d\n", 420);

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 symbol z 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文