分配后要删除什么?

时间:2015-06-13 02:13:22

标签: c++

如果我有:

template<>
char *toBytes<uint64_t>(uint64_t src) {
  char *data = new char[8];
  //...stuff
  return data;
}

template<>
void write<uint64_t>(char *dst, uint64_t src) {
  char *srcBytes = toBytes(src);
  for (int i = 0; i < 8; ++i) {
    *(dst++) = *(srcBytes++); //am I leaking here?
  }
}

用以下内容调用:

char *keyPtr = new char[27];
//...stuff
write(keyPtr, 1234ull);
//...write up to 27

如果delete[] keyPtr;我删除了srcBytes吗?我想问的问题是,在问我是否在泄漏时,是否正在复制,因此删除keyPtr仍然要删除srcBytes

仍在学习C ++,并且在调用复制构造函数与赋值运算符时,并不总是很清楚。

编辑1

根据@Steephen的回答修复删除

编辑2

根据@ WhozCraig的评论

添加toBytes

3 个答案:

答案 0 :(得分:3)

你必须使用

delete [] keyPtr;

而不是调用delete for for循环;

如果使用new[]分配内存,则应使用delete [],如果使用new,则应使用delete。在你的情况下,你正在使用前一个。

  

我认为问题是,在线询问我是否在泄漏,就是这样   做一个副本,结果删除keyPtr离开srcBytes

如果您的程序使用new运算符为srcBytes分配内存,则应将其删除,方法与keyPtr相同。因为两个指针的资源处理在您的情况下分配后都是独立的。

答案 1 :(得分:1)

你有内存泄漏。不,delete [] - ing keyPtrsrcBytes无关,这是一项独立分配。两个已寻址的缓冲区不相关(由于您的复制代码,内容除外)。

除了显而易见的(使用std::vector<>并让RAII接管所有这些的内存管理),对代码插入泄漏的相当小的更改将循环如下:< / p>

template<>
void write<uint64_t>(char *dst, uint64_t src) 
{
    char *srcBytes = toBytes(src);
    std::copy(srcBytes, srcBytes+8, dst);
    delete [] srcBytes;
}

或使用智能指针:

template<>
void write<uint64_t>(char *dst, uint64_t src) 
{
    std::unique_ptr<char[]> srcBytes(toBytes(src));
    std::copy(srcBytes.get(), srcBytes.get()+8, dst);
}

两者都使用std::copy stock算法,它既能完成您想要的效果,又能保留toBytes的原始结果,以便进行适当的清理。你选择哪个(或者可能是完全不同的东西)我留给你。

祝你好运。

答案 2 :(得分:1)

在某些情况下,您会泄漏使用“new”的内存:

  • 在删除函数之前,函数会超出作用域,并且没有指向函数外部已分配内存的指针。
  • 您忘了删除适当的地方
  • 您混合deletedelete []
  • 使用“新”和“删除”之间存在例外。

即使是初学者,熟悉智能指针也是个好主意。