在 class B 的构造函数中动态创建 vector<class A>,当 class A 在构造时分配内存

dynamically create vector<class A> inside constructor of class B, when class A allocates memory when constructed

我是一名嵌入式开发人员。现在我参与了一个使用 c++ 的项目,因为我们的 µC 不支持 c++,所以我的 c++ 变得有点生疏了。我希望你们中的一些人能帮助我。

我想模拟一个具有动态数据长度和从设备数量的 SPI 总线连接。 由于此代码测试了一些用普通旧 C 编写的 µC 代码,因此有必要让 symulation-Interface 使用数组而不是容器。

这是我声明的 classes,下面是我的问题描述。

class LSPI_BusSymulation_SlaveDevice;

class LSPI_BusSymulation{ //Interface to the Symulation-Klass
public:
    LSPI_BusSymulation(uint16_t dataSizePerDevice, uint16_t maxNumberOfDevices, uint16_t actualNumberOfDevices);

    // must use normal arrays
    uint16_t* sendSpiData(uint16_t* data, uint16_t dataSize);
private:
    uint16_t actualNumberOfDevices;
    std::vector<LSPI_BusSymulation_SlaveDevice> devices;
};

class LSPI_BusSymulation_SlaveDevice{//Symulates one bus-device, there can be several
    friend LSPI_BusSymulation;
public:
    LSPI_BusSymulation_SlaveDevice(uint16_t dataSizePerDevice, uint16_t maxNumberOfDevices);
    ~LSPI_BusSymulation_SlaveDevice();

    // must use normal arrays
    void prepareResponse(uint16_t* data, uint16_t dataSize);
    uint16_t* getBusData();

private:
    // must use normal arrays
    uint16_t* putData(uint16_t* data, uint16_t dataSize);

    uint16_t dataSizePerDevice;
    uint8_t* data;
};

class LSPI_BusSymulation 应在其构造函数中创建一个带有 actualNumberOfDevices * LSPI_BusSymulation_SlaveDevice 的向量。 如何在不产生内存泄漏的情况下正确实现 LSPI_BusSymulation 的构造函数? 这是我到目前为止所拥有的。 (其他方法暂时不重要)

LSPI_BusSymulation_SlaveDevice::LSPI_BusSymulation_SlaveDevice(uint16_t dataSizePerDevice, uint16_t maxNumberOfDevices)
    : dataSizePerDevice(dataSizePerDevice){
    data = new uint8_t[dataSizePerDevice * (maxNumberOfDevices + 1)];
}

LSPI_BusSymulation_SlaveDevice::~LSPI_BusSymulation_SlaveDevice(){
    delete data;
}

void LSPI_BusSymulation_SlaveDevice::prepareResponse(uint16_t* data, uint16_t dataSize){
    memcpy(this->data, data, dataSize);
}

uint16_t* LSPI_BusSymulation_SlaveDevice::getBusData(){
    return (uint16_t*)this->data;
}

uint16_t* LSPI_BusSymulation_SlaveDevice::putData(uint16_t* data, uint16_t dataSize){
    memcpy(&this->data[this->dataSizePerDevice], data, dataSize);

    return (uint16_t*)this->data;
}

LSPI_BusSymulation::LSPI_BusSymulation(uint16_t dataSizePerDevice, uint16_t maxNumberOfDevices, uint16_t actualNumberOfDevices)
    : actualNumberOfDevices(actualNumberOfDevices){
    //create a vector with actualNumberOfDevices * LSPI_BusSymulation_SlaveDevice
    //Does that work, or will I lose the array inside the created class?
    for(int i = 0; i < actualNumberOfDevices; i++)
        devices.push_back(LSPI_BusSymulation_SlaveDevice(dataSizePerDevice, maxNumberOfDevices));
}

uint16_t* LSPI_BusSymulation::sendSpiData(uint16_t* data, uint16_t dataSize){
    uint16_t* retPtr = data;

    for(int i = 0; i < this->actualNumberOfDevices; i++)
        retPtr = devices[i].putData(retPtr, dataSize);

    return retPtr;
}

我看到很多关于这个问题的帖子,但是这些帖子中有 none 个 class 里面有动态分配的内存。我不确定这是否是个问题。

如果我运行这个简单的main:

int main(){    
    LSPI_BusSymulation test(10, 10, 10);

   return 0;
}

我收到以下错误: * `./a.out' 中的错误:双重释放或损坏(fasttop):0x0000000000ea0c20 *

希望我提供了所有信息。

如果您使用 C++,以这种方式使用标准容器,您将不必担心释放内存。如果您想检索原始数组指针,您始终可以访问容器分配的数据。

您的代码的一些示例修改

class LSPI_BusSymulation{
...
private:
    // must use normal arrays
    uint16_t* putData(uint16_t* data, uint16_t dataSize);

    uint16_t dataSizePerDevice;
     std::vector<uint8_t> data;
};

构造函数:

LSPI_BusSymulation_SlaveDevice::LSPI_BusSymulation_SlaveDevice(uint16_t dataSizePerDevice, uint16_t maxNumberOfDevices)
    : dataSizePerDevice(dataSizePerDevice){
    data.resize(dataSizePerDevice * (maxNumberOfDevices + 1));
}

获取数据(示例代码)

uint16_t* LSPI_BusSymulation_SlaveDevice::getBusData(){
    return (uint16_t*)this->data.data(); // access to the container underlying allocated raw data
}