You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用类指针数组时指针算术运算失效的原因咨询

指针算术运算失效的原因分析

我正在进行指针实验,无法理解以下代码为何运行异常。我知道应使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 23:45:40