由strcpy设置解除分配char *时的内存泄漏?

时间:2017-09-29 10:47:20

标签: c++ memory-leaks

我有一个内存泄漏检测器工具,告诉我下面的代码泄漏了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?

2 个答案:

答案 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)