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

时间:2015-02-24 13:51:25

标签: c++ vector dynamic-allocation

在动态分配struct之后,我认为放置'删除'是谨慎的。在末尾。但它给了我一个运行时错误。虽然编译好了。因此,如果我摆脱'删除',它运行正常。但我担心可能会有内存泄漏。处理此代码的安全方法是什么?

#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;
}

3 个答案:

答案 0 :(得分:6)

delete[]的来电与delete的来电不同(请注意方括号)。

您将delete的来电与new的来电以及delete[]的来电与new SomeType[someCount]的来电配对。

在您的情况下,您分配了一个对象,而不是一个数组。您的对象碰巧表示一个向量,它是一个数组,但它与C ++无关:您使用“单个”new分配它,因此您无法应用“数组” delete[]到它。

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

delete mtx;

注意:您应该动态分配std::vector<T>的情况很少。代表std::vector<T>本身的对象非常小;数据存储在其他地方,并动态分配。所以你不妨使用

VecStrInt mtx;

并完全跳过delete

答案 1 :(得分:1)

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

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

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

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

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

答案 2 :(得分:0)

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

C ++分配和解除分配事物的方式是通过构造函数/析构函数完成的,称为RAII。标准类通过它们的构造函数/析构函数为您处理。您可以使用例如:

  • 标准容器,例如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;
}

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

#include <string>

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