使用类指针数组时指针算术运算失效的原因咨询
指针算术运算失效的原因分析
我正在进行指针实验,无法理解以下代码为何运行异常。我知道应使用STL容器而非裸指针,但好奇该问题的原因。
假设有如下Example类:
class Example { public: Example() :number{10} { std::cout << "From Example Class " << std::endl; } ~Example() { std::cout << "Destructor from Example Class" << std::endl; } void print() { std::cout << "Number from Example : " << number << std::endl; } private: int number{}; };
我们按如下方式初始化指向指针数组的指针:
// 指向指针数组的指针 Example** ex_ptr_array{ new Example * [4] }; for (size_t i = 0; i < 4; i++) { ex_ptr_array[i] = new Example{}; }
我可以通过以下方式解引用指针并调用对象方法,无需使用->运算符:
(*ex_ptr_array[0]).print(); // 输出:Number from Example : 10
也可以使用数组方式结合->运算符调用对象方法:
ex_ptr_array[2]->print(); // 输出:Number from Example : 10
但我无法理解为何以下指针算术运算无法正常工作:
// 为什么这个不行? (*ex_ptr_array + 1)->print(); // 输出随机值:Number from Example : -33686019
请问该指针算术运算失效的原因是什么?
问题根源:运算符优先级与指针类型误解
1. 运算顺序完全不符合预期
在C++中,*ex_ptr_array + 1的执行逻辑和你想的不一样:
*ex_ptr_array等价于ex_ptr_array[0],也就是拿到指针数组里第一个Example*类型的指针。- 当你给这个指针加
1时,指针算术会按照Example对象的大小(sizeof(Example))进行偏移,最终得到的是指向第一个Example对象之后内存区域的野指针。
这个野指针指向的内存根本不是一个合法的Example对象,所以调用print()时访问的number是未初始化的垃圾值。
2. 正确的指针数组算术写法
如果你想通过指针算术访问指针数组的下一个元素,需要先对ex_ptr_array做算术运算,再解引用:
(*(ex_ptr_array + 1))->print(); // 或者更简洁的等价写法: ex_ptr_array[1]->print();
这里ex_ptr_array + 1是让指向指针数组的指针偏移一个Example*的大小,移动到数组第二个元素的位置,解引用后得到的是合法的Example*指针,调用print()就能得到正确结果。
3. 对比正确写法的逻辑
你之前的(*ex_ptr_array[0]).print()能正常工作,是因为ex_ptr_array[0]先拿到第一个Example*,解引用后得到合法的Example对象;ex_ptr_array[2]->print()则是直接通过下标访问数组中第三个Example*指针,逻辑完全正确。
内容的提问来源于stack exchange,提问作者the_parzival
相关产品推荐
相关产品推荐

