- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
strdup 是否每次都分配另一个内存区域并创建另一个指针?
例如:下面的代码会导致内存泄漏吗?
void x(char** d, char* s){
*d = strdup(s);
}
int main(){
char* test = NULL;
x(&test, "abcd");
x(&test, "etc");
return 0;
}
最佳答案
是的,程序会泄漏内存,因为它分配对象然后丢失对它们的引用。
第一次发生这种情况是在行中:
x(&test, "etc");
变量 test
保存了在之前调用 x
时分配的指针的唯一副本。对 x
的新调用会覆盖该指针。那时,指针泄漏。
这就是内存泄漏的含义:丢失对现有动态分配的存储空间的所有引用。*
第二次泄漏发生在 main
函数返回时。那时,test
变量被销毁,并且该变量保存着指向 "etc"
字符串副本的指针的唯一副本。
有时在 C 程序中,我们有时并不关心第二种类型的泄漏:程序终止时未释放的内存,但不会在循环中一遍又一遍地分配(因此不会导致失控内存增长问题)。
如果程序曾被集成到另一个程序中(例如作为共享库),其中原始的 main
函数变成了可以在同一程序环境中重复调用的启动函数,那么这两种泄漏会变成问题。
POSIX strdup
函数的行为与此类似:
char *strdup(const char *orig)
{
size_t bytes = strlen(orig) + 1;
char *copy = malloc(bytes);
if (copy != 0)
memcpy(copy, orig, bytes);
return copy;
}
是的;它每次都会分配新的存储空间。
如果您的 C 镜像中有垃圾收集器(例如 Boehm),那么泄漏的存储空间可能会被回收,因此 strdup
能够为第二次分配。 (但是,垃圾收集器不会在一次分配后启动,除非它在压力测试模式下运行以清除错误。)
现在,如果你真的想通过 realloc 重用内存,那么你可以按照这些行更改你的 x
函数:
#include <stdlib.h>
#include <string.h>
void *strealloc(char *origptr, char *strdata)
{
size_t nbytes = strlen(strdata) + 1;
char *newptr = (char *) realloc(origptr, nbytes); /* cast needed for C++ */
if (newptr)
memcpy(newptr, strdata, nbytes);
return newptr;
}
(顺便说一句,以 str
开头的外部名称位于 ISO C 保留命名空间中,但 stralloc
是一个很好的名称,无法拒绝。)
请注意,界面不同。我们不传递一个指向指针的指针,而是呈现一个类似于 realloc
的接口(interface)。调用者可以检查 null 的返回值以检测分配错误,而不会在这种情况下不方便地用 null 覆盖指针。
main
函数现在看起来像:
int main(void)
{
char *test = strealloc(NULL, "abcd");
test = strealloc(test, "etc");
free(test);
return 0;
}
和以前一样,没有错误检查。如果第一个 stralloc
失败,则 test
为 null。那不是因为它无论如何都会被覆盖,并且 strealloc
的第一个参数可能为 null。
只需要一个 free
来堵住内存泄漏。
* 程序没有丢失引用的对象可能会发生语义内存泄漏。例如,假设一个程序不断地向列表中添加信息,该列表从未用于任何目的并且只是不断增长。
关于c - strdup 和内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20711970/
与 strdup 一起工作时在 Windows 上我发现 _strdup是 Windows 特定的,但是当我在 Linux 上运行相同的代码时,它需要 strdup没有下划线。有谁知道这种差异背后的历
我正在阅读“操作系统:三个简单的部分”。在第 5 章中,有一段代码展示了 exec() 系统调用的用法。 1 #include "common.h" 2 3 int main(
关闭。这个问题需要details or clarity .它目前不接受答案。 想要改进这个问题吗? 通过 editing this post 添加详细信息并澄清问题. 关闭 2 年前。 Improve
我调用 strdup 来复制 set_device( devname ) 中的“card”字符串set_device( 设备名称 )然后我使用“card”打开混音器: devname 的格式为 hw:
我有一个用 C 编写的应用程序。我在那里使用 strdup 来复制 char*。在调用 strdup 之前,我正在验证源字符串。即使 strdup 正在转储核心,它也不等于 NULL。 这是回溯 #0
可能这是非常基本的问题,每个人都会对我大喊大叫,但我已经尝试解决这个问题几个小时了,但再也无法忍受了。我有这个结构 struct node { Key_Type element; tree_ptr l
我必须分配一个包含 1000 个字符串指针的数组,从 stdin 中读取每个字符串,并将每一行的 strdup 读入数组中。我做了以下事情: char *array[1000]; int index
我在线程函数中使用下面的 get_sessionid() 函数,然后尝试释放该指针。 static char sessionid[SESSIONID_LEN] = { '\0' }; static v
我正在实现一个 strdup 函数作为练习。 char* strdupPtr(const char* str) { const size_t sz{strlen(str)+1}; ch
我正在尝试这段代码: imei=Found_imei(pClient->GetBuffer()); printf("6. CODICE IMEI %s \n",imei); pClient->SetI
我实现了一个返回字符串的函数。它接受一个整数作为参数 (age),并返回一个格式化的字符串。 除了我有一些疯狂的内存泄漏之外,一切都运行良好。我知道 strdup() 是造成这种情况的原因,但我试图研
如果输入的 const 字符串以某种方式被修改(这会导致 C 编译器警告),那么处理它的最佳方法是什么 - 将其类型转换为新变量然后使用它或复制它并使用它然后然后释放它。或者有没有其他方法可以处理这种
在我从前人那里继承的程序中,有以下格式的功能: somefunc(some_type some_parameter, char ** msg) 换句话说,最后一个参数是一个char **,用来
我正在为一本书编写一个 C++ 类,其中包含一个名字: class Book { private: char* nm; .......... ............ .......... .
我将 VTK 与 MSVC 一起使用,并在尝试加载数据时出现奇怪的行为。我对它进行了一些修改,甚至下面的代码也会产生堆损坏,知道发生了什么或可能出了什么问题吗? vtkAbstractArray *v
我有这样的类(class): class Kot{ public: string name; }; 我创建了它的一个实例: Kot* kot = new Kot; kot->name = "J
strdup 是否每次都分配另一个内存区域并创建另一个指针? 例如:下面的代码会导致内存泄漏吗? void x(char** d, char* s){ *d = strdup(s); } in
当我在做作业时,我开始知道我们不应该使用这样的作业: char *s="HELLO WORLD"; 使用这种语法的程序很容易崩溃。 我试过并使用过: int fun(char *temp) {
我正在调用 strdup 并且必须在调用 strdup 之前为变量分配空间。 char *variable; variable = (char*) malloc(sizeof(char*)); var
我最近意识到我在 OS X 上经常使用的 strdup() 函数不是 ANSI C 的一部分,而是 POSIX 的一部分。我不想重写我所有的代码,所以我想我只是要编写我自己的 strdup() 函数。
我是一名优秀的程序员,十分优秀!