简体   繁体   English

C++ 指针移动

[英]C++ Pointer movement

int main() 
{ 
    char *A[] = { "abcx", "dbba", "cccc"}; 
    char var = *(A+1) - *A+1; 
    cout << (*A + var); 
} 

Hi, the code gives output bba.嗨,代码给出了输出 bba。 I am unable understand, how the integer value of var becomes 6. In what order, the var value is solved.我无法理解var的整数值是如何变成6的,var值是按什么顺序求解的。 Please explain.请解释。 Thanks in advance.提前致谢。

A is an array of pointers to character arrays. A 是指向字符数组的指针数组。 AKA, strings.又名,字符串。 Each array is 5 characters long because of the 4 character string literals, each of which has one hidden null terminator.由于 4 个字符串文字,每个数组有 5 个字符长,每个字符串文字都有一个隐藏的空终止符。

Because you got lucky and your compiler does the simple thing , the character literals are placed into the program one after the other.因为你很幸运并且你的编译器做了简单的事情,字符文字一个接一个地放入程序中。

So *A is the address of the first array.所以 *A 是第一个数组的地址。 *(A+1) is the address of the second array. *(A+1) 是第二个数组的地址。 Subtract them and that is 5. Add 1 for 6.减去它们就是 5。 6 加 1。

This kind of C code is obfuscated.这种 C 代码被混淆了。 It can also be dangerous.它也可能是危险的。 I would not rely on accessing through a pointer outside of an array even if you are pretty sure there's a second array following.即使您非常确定后面有第二个数组,我也不会依赖于通过数组外的指针进行访问。 Assuming that will only lead to pain.假设那只会导致痛苦。 And suffering.和痛苦。

Because *A + var when var is greater than the array size is undefined behavior .因为*A + varvar大于数组大小时是未定义行为 In this case the valid array size is 5, so valid values of var are 0..4.在这种情况下,有效数组大小为 5,因此var有效值为 0..4。

Undefined behavior means that the compiler's optimizer is allowed to assume that it does not happen.未定义行为意味着允许编译器的优化器假设它不会发生。 Because if your program DID have undefined behavior, it would not be a defined program and would automatically be WRONG .因为如果您的程序DID具有未定义的行为,则它不会是已定义的程序,并且会自动为WRONG So obviously you'd never do that.所以很明显你永远不会那样做。 Hah.哈。

Here's some modified code that will hopefully explain better:下面是一些修改后的代码,希望能更好地解释:

#include <iostream>

int main() {
  char *A[] = {"abcx", "dbba", "cccc"};
  char var = *(A + 1) - *A + 1;
  std::cout << (void *)*A << std::endl;
  std::cout << (void *)*(A + 1) << std::endl;
  std::cout << (*A + var) << std::endl;
  return 0;
}

Running it:运行它:

0x402010
0x402015
bba

Those are memory addresses on my particular machine, yours may be different.这些是我特定机器上的内存地址,你的可能不同。 But the important thing is they are 5 bytes different.但重要的是它们有 5 个字节不同。

Now I'm going to use a hex dump tool called xxd .现在我将使用一个名为xxd的十六进制转储工具。 You can find other good ones.你可以找到其他好的。 If I dump the binary executable as hex and search for dbba I find a line:如果我将二进制可执行文件转储为十六进制并搜索dbba我会找到一行:

00002010: 6162 6378 0064 6262 6100 0000 011b 033b  abcx.dbba......;

Oh wait, let me rebuild that without optimization.哦等等,让我在没有优化的情况下重建它。 See what I mean about this being risky business?明白我所说的这是有风险的业务是什么意思吗?

00002010: 6162 6378 0064 6262 6100 6363 6363 0000  abcx.dbba.cccc..

The optimizer had completely removed the third array element from the binary because no one used it.优化器已经从二进制文件中完全删除了第三个数组元素,因为没有人使用它。

If we'd written the code just a little differently the optimizer could have removed both the second and third array element and you'd be trying to print binary garbage data.如果我们想编写的代码不同的只是一个小的优化可能已经删除了第二和第三阵元你会尝试打印二进制垃圾数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM