为什么在递增后使用 [] 运算符访问指针数组会返回错误地址的当前内存位置

Why does accessing pointer array using [] operator after increment the current memory position of return bad address?

本文关键字:错误 返回 数组 地址 位置 内存 指针 访问 运算符 为什么      更新时间:2023-10-16

我知道使用指针算法有副作用,但我无法弄清楚这背后发生了什么

int * pointer_arr = new int [ 3 ] { 10, 11, 12 };
std::cout << * pointer_arr ++ << std::endl; // output 10 then increment
std::cout << ++ * pointer_arr << std::endl; // access then increment => output 12
++ * pointer_arr;
std::cout << pointer_arr [ 0 ] << std::endl; // should output 13
std::cout << pointer_arr [ 1 ] << std::endl; // should output 11
std::cout << pointer_arr [ 2 ] << std::endl; // should output 12, but this output 0 instead
delete [] pointer_arr;
// output
// also, it miss another element of 11
10
12
13
13
12
0

另外,如果我尝试用括号包装第一个

std::cout << ( * pointer_arr ) ++ << std::endl;

输出将是

10
12
13
13
11
12

这就是我期望上面会打印出来的。然后,如果我在输出 12 的行之后添加另一行移动到下面的第二个索引,

std::cout << * ++ pointer_arr << std::endl;

这种情况会发生

10
12
11
12
12
12
-1342177820

我正在尝试理解指针的基本原理,我知道对指针进行算术运算有副作用,但这让我感到困惑。请帮助我解释为什么在上面的某些操作或指针算术之后使用 [] 运算符输出数组的最后一个索引会导致意外结果以及括号环绕指针和没有括号环绕之间的差异。

表达式* pointer_arr ++将增加指针,而不是它指向的元素。这意味着它将不再指向数组中的第一个元素,而是指向第二个元素。这也意味着pointer_arr[2]超出界限,因为它是三元素数组的第四个元素。

然后您将修改后的指针传递给delete[] .必须将原始指针传递给 delete[]

取消引用和delete[]都将导致未定义的行为

这是运算符优先级的问题,其中后缀++运算符的优先级高于取消引用运算符*。这意味着* pointer_arr ++实际上是* (pointer_arr ++)