如果我有:
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答案 0 :(得分:3)
你必须使用
delete [] keyPtr;
而不是调用delete
for for循环;
如果使用new[]
分配内存,则应使用delete []
,如果使用new
,则应使用delete
。在你的情况下,你正在使用前一个。
我认为问题是,在线询问我是否在泄漏,就是这样 做一个副本,结果删除keyPtr离开srcBytes
如果您的程序使用new运算符为srcBytes
分配内存,则应将其删除,方法与keyPtr
相同。因为两个指针的资源处理在您的情况下分配后都是独立的。
答案 1 :(得分:1)
你有内存泄漏。不,delete []
- ing keyPtr
与srcBytes
无关,这是一项独立分配。两个已寻址的缓冲区不相关(由于您的复制代码,内容除外)。
除了显而易见的(使用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”的内存:
delete
和delete []
即使是初学者,熟悉智能指针也是个好主意。