在 C++ 中动态分配向量的安全方法是什么

What's the safe way to dynamically allocate vector in C++

动态分配结构后,我认为将 'delete' 放在末尾是明智的。但它给了我一个运行时错误。不过编译没问题。因此,如果我摆脱 'delete',它运行良好。但我担心可能会发生内存泄漏。处理此代码的安全方法是什么?

#include <iostream>
#include <vector>
using namespace std;

typedef struct
{
    vector<char*> vstr;
    vector<int> vint;

}VecStrInt;

int main()
{
    VecStrInt * mtx = new VecStrInt();

    mtx[0].vstr.push_back("Hello");
    mtx[0].vint.push_back(1);

    cout<<mtx[0].vint.at(0)<<endl;
    cout<<mtx[0].vstr.at(0)<<endl;

    //delete [] mtx;

    return 0;
}

delete[]的调用与delete的调用不同(注意方括号)

您将 delete 的调用与 new 的调用配对,并将 delete[] 的调用与 new SomeType[someCount] 的调用配对。

在你的例子中,你分配了一个对象,而不是一个数组。您的对象恰好 表示 一个向量,它是一个数组,但这对 C++ 无关紧要:您用 "single" new 分配了它,所以您不能对其应用 "array" delete[]

因此,您需要 delete 使用常规删除运算符:

delete mtx;

注意:很少有需要动态分配 std::vector<T> 的情况。表示std::vector<T>的对象本身很小;数据存储在别处,并动态分配。所以你不妨使用

VecStrInt mtx;

并完全跳过 delete

如果像这样只分配一个对象,则必须使用运算符 delete

VecStrInt * mtx = new VecStrInt();
//...
delete mtx;

如果你分配一个对象数组(即使数组只包含一个元素)你必须像这样使用运算符delete[]

VecStrInt * mtx = new VecStrInt[1];
//...
delete [] mtx;

您也可以使用标准智能指针,例如 std::unique_ptr

如果你真的想要安全,你不应该像这样直接使用new/delete,因为在你的函数和[=13=中间可能会抛出异常] 子句将不会被执行。

分配和解除分配事物的 C++ 方法是通过 constructors/destructors 完成的,称为 RAII。标准 类 通过他们的 constructor/destructor 为您处理。您可以使用例如:

  • 标准容器,如 std::vector<T> 用于多个元素,而不是 T* = new T[]
  • std::string 用于字符串而不是 char*
  • 智能指针,由C++11标准引入(仅适用于更复杂的情况):std::unique_ptr<T>std::shared_ptr<T>/std::weak_ptr<T>

注意:在你的例子中,mtx只在main函数内部使用,所以你不需要在堆上分配它,你可以只写:

int main()
{
    VecStrInt mtx;

    mtx.vstr.push_back("Hello");
    mtx.vint.push_back(1);

    cout << mtx.vint.at(0) << endl;
    cout << mtx.vstr.at(0) << endl;

    return 0;
}

同样,你应该在VecStrInt中使用std::string而不是char*,以避免字符串内存泄漏:

#include <string>

struct VecStrInt
{
    vector<string> vstr;
    vector<int> vint;
};