在动态分配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;
}
答案 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*
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;
};