tl; dr 如果不调用临时指针,可以天真地使用asprintf
进行连接吗?
GNU引入并在其他几个clib实现中采用的函数asprintf
是一个诱人的解决方案,可以使用像
int i=0;
char *str = strdup(argv[i]);
while (argv[++i]) {
asprintf(&str,"%s %s",argv[i],str); // <=== This line
}
asprintf(&str,"%s\n",str);
当包裹在主要和必要的包含中时,这对我来说运行正常。
它是否在整个地方泄漏了内存? Valgrind说它在我的盒子上。这是一个错误吗?
我面前的男人页面说
asprintf()和vasprintf()函数将* ret设置为指向a的指针 缓冲区足够大以容纳格式化的字符串。这个指针 应该传递给free(3)以释放分配的存储空间 不再需要。如果无法分配足够的空间,asprintf() 和vasprintf()将返回-1并将ret设置为NULL指针。
由于短语“将*ret
设为指向新缓冲区[...]”的指针,我很想参加假设该函数使用realloc
作为getline
。
使用签名int asprintf(char **ret, const char *format, ...);
来实现具体性。
asprintf
过早运行realloc
。
想象一下,我们实现了这个函数,我们可以运行realloc(*ret)
,然后取消引用其中一个混淆原始缓冲区的变量。该缓冲区已被释放,这在技术上是未定义的行为。这将代表一个错误。
asprintf
在读取之前写入缓冲区。在上面的代码中,我们可以将argv[1]
的内容复制到*ret
va_arg
str
asprintf
之前的函数。我引用的联合页面似乎并没有统治这种情况。
free *ret
不会realloc
直接或通过使用asprintf
。这将避免问题编号(1),但如果如上所述使用会泄漏内存。同样,该手册页似乎不排除它。
使用
替换单{
char *newStr = NULL;
asprintf(newStr,"%s %s",argv[i],str);
free(str);
str = newStr;
}
次呼叫可以避免上述所有情况
{{1}}
但这很笨重。
协商一致实施是否保证第一个代码示例安全无误?
答案 0 :(得分:3)
它是否在整个地方泄漏记忆?
是的,确实如此。
char *str = strdup(argv[i]);
此处,str
包含指向malloc()
内存的指针,该内存应为free()
d。
asprintf(&str, "%s %s", argv[i], str);
这里,asprintf()
修改str
,使其指向函数本身分配的其他内存。现在你丢失了指向strdup()
ped字符串的指针,因此泄漏了。