struct temp
{
char *a;
};
vector<struct temp> array;
void AddData(char *p1, char *p2)
{
struct temp t1;
t1.a=new char[strlen(p1)+1];
strcpy(t1.a,p1);
array.push_back(t1);
}
现在,如果我每次AddData()
都打电话,那么如果我在delete[]
t1.a
之后调用push_back()
,我将会在以后打印矢量数组时出现问题。我该如何解决这个问题?
答案 0 :(得分:3)
这段代码编码风格很差。但是它不会泄漏任何内存本身。您使用new[]
分配的内存仍由全局向量的元素指向;所以程序的其余部分以后可以delete[]
那个记忆。
(它与您编写的示例char *foo = new char[20]; return;
不一样 - 这20个字节将被泄露)。
如果您没有意识到,会发生的事情是vector元素和本地副本t1
都包含一个指针;这两个指针都指向分配内存的同一块。没有&#34;魔法&#34;分配另一个内存块或任何东西。
执行delete[]
后,您不应该致电push_back
。这将删除向量中仍由指针指向的内存;当你去使用向量时导致未定义的行为。
一般情况下,您应为每个delete[]
执行一次new[]
;在这段代码中,完成它的时间就是你完成了向量;此时,您可以清除向量并删除其中的指针。
NB。当然,最好完全放弃这种方法,并使用管理自己内存的容器,正如其他人所建议的那样。这样做很容易无意中delete[]
内存两次,或者根本不删除它。
答案 1 :(得分:2)
您不需要new/delete
管理内存,并且可以使用std::string
作为字符串。
struct temp
{
std::string a;
};
std::vector<temp> array;
void AddData(char *p1, char *p2)
{
temp t1;
t1.a = std::string(p1);
array.push_back(t1);
}
此外,当你delete
指针时,它只是取消分配内存并调用它的析构函数(如果它有一个)。你有垃圾,因为你没有分配内存,尝试从向量中删除项目。
如果您不想删除该项,则可以在取消分配后将指针设置为0
。现在,您知道指针指向任何内容,您可以避免取消引用它。
答案 2 :(得分:2)
您将指向数组的指针放入vector
,而不是数组内容。因此,如果您在将对象插入向量后立即delete
指针,则稍后访问它将是未定义的。为了避免内存泄漏,您需要在从向量中删除其引用时删除该数组,而不是之前。
有几种方法可以做到这一点。对于包含字符串的字符数组的特定情况,您可以使用std::string
代替。另一种方法是将复制构造函数和赋值运算符添加到temp
,将数组复制到向量中temp
所拥有的新数组中,然后将析构函数添加到temp
删除数组(或更好的是,使用智能指针,如std :: unique_ptr,为您处理清理)。