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

C++通过指针遍历vector<Apple*>元素输出0的问题求解

问题根因

你的代码错误来自对指针算术逻辑的误解:

  • 你定义的Apple* ptr = apples[0]是直接指向第一个new出来的Apple实例的指针,三个Apple实例是独立调用new分配的堆内存,内存地址不连续。对ptr执行++操作时,指针会向后偏移1个Apple对象的内存长度,这个偏移后的地址不属于任何你创建的Apple实例,属于非法野指针访问,读到的是内存里的随机值,所以输出0。
  • vector内的元素确实是连续存储的,但你存的元素类型是Apple*,连续排列的是这些指针本身,不是指针指向的Apple对象。你拿第一个Apple对象的地址做偏移,根本访问不到vector里存的下一个指针。
正确实现

给你三种可直接运行的正确遍历写法,包含你之前尝试没写对的迭代器版本:

#include <iostream>
#include <vector>

class Apple{
public:
    int size;
    Apple(int size): size(size){}
    void print(){
        std::cout << size << '\n';
    }
};

std::vector<Apple*> apples = {new Apple(21), new Apple(37), new Apple(66)}; 

// 1. 迭代器遍历(你之前尝试的错误写法是没搞懂迭代器的解引用层级)
void traverseByIterator() {
    for (auto it = apples.begin(); it != apples.end(); ++it) {
        // it是指向vector元素的迭代器,*it拿到vector里存的Apple*指针,再用->访问对象成员
        (*it)->print();
    }
}

// 2. 指针对齐偏移遍历(对应你原来想写的ptr自增逻辑)
void traverseByPointer() {
    // 要定义指向vector元素的二级指针,因为vector存的元素是Apple*,元素首地址类型是Apple**
    Apple** ptr = apples.data();
    for (size_t i = 0; i < apples.size(); ++i) {
        (*ptr)->print();
        ptr++; // 每次偏移一个Apple*的长度,刚好走到下一个连续存储的vector元素
    }
}

// 3. 最简洁的范围for遍历
void traverseByRangeFor() {
    for (auto applePtr : apples) {
        applePtr->print();
    }
}

int main()
{
    traverseByIterator();
    // 用完记得释放new出来的对象,避免内存泄漏
    for (auto p : apples) {
        delete p;
    }
    return 0;
}
注意事项
  • 只有指向同一块连续内存(比如数组、vector内部存储块)的指针,做自增偏移访问后续元素才是合法行为,独立分配的堆对象地址没有连续性保证。
  • 存储指针的容器遍历要注意解引用层级:迭代器/下标拿到的是容器里存的指针,需要再访问一次才能拿到指向的对象。
  • 所有手动new出来的堆对象,必须在使用完后手动delete,否则会造成内存泄漏。

内容的提问来源于stack exchange,提问作者kolodziejpawel98

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:24:17