我有一个内存泄漏检测器工具,告诉我下面的代码泄漏了100个字节
#include <string>
#include <iostream>
void setStr(char ** strToSet)
{
strcpy(*strToSet, "something!");
}
void str(std::string& s)
{
char* a = new char[100]();
setStr(&a);
s = a;
delete[] a;
}
int main()
{
std::string s1;
str(s1);
std::cout << s1 << "\n";
return 0;
}
根据this第3点,它正在泄漏我分配的数量(100)减去"something!"
(10)的长度,我应该泄漏90个字节。
我在这里遗漏了什么,或者假设该工具报告错误是安全的吗?
编辑:setStr()
在库中,我看不到代码,所以我猜它正在这样做。它可能是在堆上分配"something!"
,那个场景怎么样?我们会有90字节的泄漏还是100?
答案 0 :(得分:3)
此代码不会泄漏,与第3点不同,因为您永远不会覆盖存储指向已分配内存的指针的变量。这段代码的潜在问题是它容易受到缓冲区溢出的影响,好像setStr
打印超过99个符号并且它不是异常安全的,好像s = a;
抛出然后delete[] a;
不会被叫,记忆会泄漏。
更新:如果setStr
分配新字符串并覆盖初始指针值,那么指向您已分配的100字节缓冲区的指针将丢失,并且这100字节泄漏。在将a
传递给nullptr
之前,您应该setStr
初始化setStr
,并在s = a;
返回后检查它是否为空,因此赋值<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
不会导致null指针解除引用。
答案 1 :(得分:1)
总结所有评论,很清楚问题是什么。您正在使用的库正在请求char **
。这是C函数的通用接口模式,它分配内存并返回指向该内存的指针,或返回指向它们拥有的内存的指针。
您泄漏的内存分配在行char* a = new char[100]();
中。由于setStr
正在更改a
的值,因此您无法再释放该内存。
不幸的是,如果没有文档,我们就无法推断出你应该用指针做什么。
如果是来自new[]
的来电,则需要致电delete[]
。
如果是来自malloc
的来电,则需要致电std::free
。
如果它是指向库拥有的内存的指针,则不应该执行任何操作。
您需要找到相关文档。但是,如果它不可用,您可以在删除new
语句后尝试使用内存泄漏检测工具,看看它是否检测到泄漏。我不确定从库函数分配的内存是否可靠,但值得一试。
最后,关于编辑中的问题,如果你泄漏了内存,你就会泄漏全部金额,除非你做了一些未定义的行为,这无论如何都是毫无意义的。如果您new
100 char
然后在其上写下一些数据,则不会更改泄露的内存量。它仍然是100 * sizeof(char)