我是否正确删除了指向对象的向量?

问题描述 投票:0回答:1

我目前正在开发一个程序,我从各种CAN信号中读取信息,并将它们存储在3个不同的向量中。对于每个信号,创建一个存储在两个向量中的指向对象的新指针。我的问题是,当我删除向量时,就足够了,当我删除指向一个向量中的对象的指针而只清除另一个向量时。

这是我的代码:

向量声明迭代器:

std::vector <CAN_Signal*> can_signals; ///< Stores all CAN signals, found in the csv file
std::vector <CAN_Signal*> can_signals_rx; ///< Stores only the Rx CAN signals, found in the csv file
std::vector <CAN_Signal*> can_signals_tx; ///< Stores only the Tx CAN signals, found in the csv file
std::vector <CAN_Signal*>::iterator signal_iterator; ///< Iterator for iterating through the varoius vectors

填充向量:

for (unsigned int i = 0; i < m_number_of_lines; ++i)
{
    string s = csv_file.get_line(i);

    CAN_Signal* can_signal = new CAN_Signal(s, i);

    if (can_signal->read_line() == false)
        return false;

    can_signal->generate_data();

    can_signals.push_back(can_signal);

    if (get_first_character(can_signal->get_PDOName()) == 'R')
    {
        can_signals_rx.push_back(can_signal);
    }
    else if (get_first_character(can_signal->get_PDOName()) == 'T')
    {
        can_signals_tx.push_back(can_signal);
    }
    else
    {
        cout << "Error! Unable to detect whether signal direction is Rx or Tx!" << endl;
        return false;
    }   
}

删除向量:

File_Output::~File_Output()
{
    for (signal_iterator = can_signals.begin(); signal_iterator != can_signals.end(); ++signal_iterator)
    {
        delete (*signal_iterator);
    }
can_signals.clear();

//for (signal_iterator = can_signals_rx.begin(); signal_iterator != can_signals_rx.end(); ++signal_iterator)
//{
//  delete (*signal_iterator);
//}
can_signals_rx.clear();

//for (signal_iterator = can_signals_tx.begin(); signal_iterator != can_signals_tx.end(); ++signal_iterator)
//{
//  delete (*signal_iterator);
//}
can_signals_tx.clear();

cout << "Destructor File_Output!" << endl;
}

当我取消注释注释的for循环并运行Programm时,它会在调用析构函数时崩溃。所以我的猜测是,这是正确的方法,因为指针已经全部删除,只需清除剩余的两个向量就足够了。

但我不太确定,并且非常希望听到专家对此的意见。

非常感谢你。

c++ object memory vector iterator
1个回答
2
投票

当我删除向量时,是否足够,当我删除指向一个向量中的对象的指针而只是清除另一个向量。

由于其他向量中的指针是副本,因此仅在一个向量中删除它们不仅足够,而且删除副本实际上具有未定义的行为。您永远不希望您的程序具有未定义的行为。

清除File_Output的析构函数中的任何向量似乎是不必要的,假设向量是File_Output的成员。这是因为无论如何,成员即将被摧毁。

我是否正确删除了指向对象的向量?

假设您没有复制您在其他地方删除的指针:是的,这是删除它们的正确方法。


您的代码有内存泄漏:

CAN_Signal* can_signal = new CAN_Signal(s, i);
if (can_signal->read_line() == false)
    return false;

如果该条件为真,那么新分配的CAN_Signal将被泄露,因为当函数返回时,指针既不被删除也不存储在任何地方。


您的代码不是异常安全的:如果抛出任何这些行,则指针会泄漏。

if (can_signal->read_line() == false)
    return false;
can_signal->generate_data();
can_signals.push_back(can_signal);

目前还不清楚,为什么你想首先使用显式内存管理。除非有理由,否则我建议您不要这样做,而是使用std::vector <CAN_Signal> can_signals。这将解决内存泄漏和异常安全问题,无需实现自定义析构函数,并使File_Output的复制/移动构造函数/赋值的实现更简单。

请注意,如果这样做,则必须reserve can_signals元素的内存以防止重新分配,因为重新分配后其他向量中的指针将失效。作为副作用,这使得程序稍微快一些。

© www.soinside.com 2019 - 2024. All rights reserved.