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

向函数传递类对象数组后无法获取settingUp设置的预期值

问题分析

向函数传递对象数组后,在main中调用printValues无法获取settingUp函数里设置的预期值——settingUp内部调用printValues能输出正确结果,但main中访问array[0]->length看似正常,访问array[2]->length直接失败。

核心原因

问题出在settingUp函数里的arrayPrueba变量:

const dataClass * arrayPrueba[3];

这是一个栈上的局部数组,当settingUp函数执行完毕后,栈帧会被销毁,arrayPrueba占用的内存会被系统回收或覆盖。而你在statusClass::setValues里把这个局部数组的地址赋值给了array成员,导致statusClass里保存的是一个悬空指针。

函数退出后,访问这个悬空指针指向的内存属于未定义行为:有时候array[0]的内存还没被覆盖,能读出值;但array[2]的内存已经被其他数据覆盖,就会出现读取失败甚至程序崩溃的情况。

另外代码里还有一个编译错误:prueba0是dataClass*类型的指针,调用成员函数应该用->而非.,正确写法是prueba0->setValues(1);,否则无法通过编译。

解决方案

以下是几种可行的修复方式,按推荐程度排序:

1. 使用std::vector管理数组(最推荐)

修改statusClass的成员,把裸指针数组换成std::vector<const dataClass*>,让容器自动管理内存:

// statusClass.h 中修改成员
#include <vector>
class statusClass {
private:
    uint8_t newStatusSelectorByte;
    std::vector<const dataClass*> array; // 替换原来的 const dataClass** array;
public:
    void setValues(uint8_t _statusSelectorByte, const dataClass** _array, size_t arraySize);
    void printValues();
};
// statusClass.cpp 实现
void statusClass::setValues(uint8_t _statusSelectorByte, const dataClass** _array, size_t arraySize){
    newStatusSelectorByte = _statusSelectorByte;
    array.clear();
    for (size_t i = 0; i < arraySize; ++i) {
        array.push_back(_array[i]);
    }
};

void statusClass::printValues(){
    printf("TP: statusClass -> printValues: Prueba = %d\n", newStatusSelectorByte);
    if (array.size() > 1) {
        printf("TP: statusClass -> printValues: arrayPrueba = %d\n", array[1]->length); 
    }
}

然后在settingUp里调用时传入数组大小:

void settingUp(statusClass *_status){
    dataClass * prueba0 = new dataClass();
    dataClass * prueba1 = new dataClass();
    dataClass * prueba2 = new dataClass();

    const dataClass * arrayPrueba[3];
    prueba0->setValues(1); // 修正为->调用
    prueba1->setValues(2);
    prueba2->setValues(3);

    arrayPrueba[0] = prueba0;
    arrayPrueba[1] = prueba1;
    arrayPrueba[2] = prueba2;

    _status[1].setValues(1, arrayPrueba, 3); // 传入数组大小
    _status[0].printValues();
}

这种方式不需要手动管理内存,避免悬空指针和内存泄漏风险。

2. 堆分配数组

把arrayPrueba改成堆上分配的数组,这样函数结束后内存不会被释放:

void settingUp(statusClass *_status){
    dataClass * prueba0 = new dataClass();
    dataClass * prueba1 = new dataClass();
    dataClass * prueba2 = new dataClass();

    // 堆分配数组
    const dataClass **arrayPrueba = new const dataClass*[3];
    prueba0->setValues(1);
    prueba1->setValues(2);
    prueba2->setValues(3);

    arrayPrueba[0] = prueba0;
    arrayPrueba[1] = prueba1;
    arrayPrueba[2] = prueba2;

    _status[1].setValues(1, arrayPrueba);
    _status[0].printValues();
}

⚠️ 注意:这种方式需要后续手动释放arrayPrueba和prueba0等堆内存,否则会造成内存泄漏。比如在statusClass的析构函数里添加:

statusClass::~statusClass(){
    delete[] array; // 释放堆数组
    // 若statusClass负责管理dataClass对象,还要释放每个元素
    for (size_t i = 0; i < 3; ++i) {
        delete array[i];
    }
}

3. 使用静态数组(不推荐)

把arrayPrueba声明为静态数组,使其生命周期和程序一致:

void settingUp(statusClass *_status){
    dataClass * prueba0 = new dataClass();
    dataClass * prueba1 = new dataClass();
    dataClass * prueba2 = new dataClass();

    static const dataClass * arrayPrueba[3]; // 添加static
    prueba0->setValues(1);
    prueba1->setValues(2);
    prueba2->setValues(3);

    arrayPrueba[0] = prueba0;
    arrayPrueba[1] = prueba1;
    arrayPrueba[2] = prueba2;

    _status[1].setValues(1, arrayPrueba);
    _status[0].printValues();
}

这种方式虽然能解决问题,但静态数组是全局共享的,多次调用settingUp会覆盖之前的值,存在线程安全问题,不建议在多线程或需要复用的场景使用。

内容的提问来源于stack exchange,提问作者David Moreno García

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 08:31:01