c++ - 如何使用 char* 修复此内存泄漏?
问题描述
我正在写一个简短的方法来获取达尔文的 MAC 地址。但是,我不断收到以下错误消息:
malloc: can't allocate region
*** mach_vm_map(size=3907498536060022784) failed (error code=3)
malloc: *** set a breakpoint in malloc_error_break to debug
我认为这是由于内存泄漏。
我尝试通过char* addr
引用传递变量,但没有成功。
我的方法是:
char* getPhysicalAddress() {
char* addr;
#ifdef __APPLE__
FILE *fp = popen("ifconfig en0 | awk '/ether/{print $2}'", "r");
if (fp != NULL) {
fscanf(fp, "%s", addr);
pclose(fp);
}
else {
addr = "[unknown]";
}
#endif
#ifdef __linux__
FILE* file = popen("cat /sys/class/net/eth0/address", "r");
if (file != NULL) {
fscanf(file, "%s", addr);
pclose(file);
}
else {
addr = "[unknown]";
}
#endif
return addr;
}
在我的主函数中,我用char* addr = getPhysicalAddress();
.
如何修复此方法中的内存泄漏?
解决方案
让我们看一下这段代码:
char* addr;
...
fscanf(fp, "%s", addr);
看起来,从这段代码中,您想从fp
文件中读取字符串addr
。但是,正如所写的那样,此代码会导致未定义的行为(哦,不!),并且在您的情况下,它看起来会破坏您的内存管理器,因此会malloc
出现错误。
那么这里发生了什么?请记住,这addr
并不是真正的字符串。相反,它是 a char*
,这意味着它是一个变量,表示“请查看我所指的位置,您会找到存储一些字符的空间”。但是,您未对其进行初始化,这意味着它指向内存中的某个随机区域,可能是您实际上并不拥有的空间。当然fscanf
后尝试将它读取的字符写入该位置时,它会破坏碰巧在该位置的任何内存,这是一件坏事。
换句话说,这不是内存泄漏。相反,它是一个未初始化的指针写入。
有几个选项可以解决这个问题。一种选择是将addr
a转换char*
为实际的字符数组,这意味着它addr
本身将表示“这里有一些空间可以放置一些字符”。您需要调整fscanf
调用以确保您没有读取太多字符,否则您将面临溢出缓冲区的风险。
或者,由于您已经用 C++ 标记了它,另一种选择是使用类似的类型std::string
来保存内存,然后使用循环从 中提取字符fp
,将它们附加到该std::string
对象。
希望这可以帮助!
推荐阅读
- php - 这是共享和关闭 PDO 连接的正确方法吗?
- ios - UIAlertController 中 TextField 之间的空间
- django - Django 对象名称,无法比较值
- javascript - Vue.js 找不到图片
- c# - 如何从 C# 中的动态 JSON 字典中提取特定值
- three.js - 围绕给定轴和角度的枢轴点正确旋转对象
- c++ - 通过输入名称和年份从特定结构中获取数据
- jdbc - 是否可以使用标准 Db2 Client JAR 连接到 IBM Db2 Event Store?
- mysql - 是否有返回列中名称列表的 MYSql 函数?该字段包含一个逗号分隔的 id 列表
- ruby-on-rails - 返回具有_many 的表C 属于表A 的表B