在向量中存储字符指针,C ++

时间:2014-06-19 06:00:11

标签: c++ memory-leaks

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(),我将会在以后打印矢量数组时出现问题。我该如何解决这个问题?

3 个答案:

答案 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,为您处理清理)。