char *a = NULL;
char *b = NULL;
方法1:char *malloc_string(int string_size){
return (char*)malloc(string_size);
}
a=malloc_string(4);
free(a);
方法2:void malloc_string(char **a, int string_size){
*a = (char*)malloc(string_size);
}
malloc_string(&b, 4);
free(b);
你会选择哪一个,为什么?
两个都不好。
-
不要有
malloc
的存根函数,因为你的代码对阅读你的代码的人来说变得不太清楚。(malloc
是一个标准函数,每个人都知道它是做什么的) -
并且不要将
malloc
投射到=
的右侧:这是糟糕的编程风格,因为(i)你在重复自己,(ii)有人重构你的代码可能会改变一个而不是另一个地方的指针类型。
要回答这个问题,TL;DR,任意一个。都可以。
挑毛病,NONE,因为
-
两种方法都缺少错误检查。那么包装有什么用呢?
1.1。如果我传递
string_size
作为-ve值,malloc()
将爆炸。1.2。在使用返回的指针之前,应该检查
malloc()
失败(或成功)。 - 请查看为什么不将
malloc()
和family的返回值强制转换为C
。
在C中,正确的方法是一开始就不定义malloc_string()
,它只是引入了一个不必要的(希望是优化的)函数调用。只需这样做:
a = malloc(4);
参见我是否强制转换malloc的结果?
除此之外,你的参数类型是错误的,它必须是size_t
,而不是int
(你的编译器应该警告你,启用编译器警告)
malloc
周围定义一个单个包装器来处理中心位置的错误…它的最简单形式是这样的:
void *xmalloc(size_t size)
{
void *ret;
if (!(ret = malloc(size))
{
/* perror("malloc"); */
exit(1);
}
return ret;
}
唯一值得替换的是free(), C标准并没有说释放内存后指针必须为null;
#define SAFE_FREE(m)
{
if(m)
{
free(m);
m = NULL;
}
}
一个好的做法是将释放的指针设置为NULL,这将有助于更早地发现潜在的问题,特别是如果您习惯于对每个内部函数使用assert,如:
void foo_internal(void* p)
{
assert(p != NULL);
// ...
}
如果在释放指针并调用函数后不设置NULL,那么在大多数编译器和平台上都不会触发断言(内存分配是特定于平台的)。
如果你有IDE调试器,可以逐步完成代码,但在某些情况下,如UEFI,嵌入式等,你没有调试器,简单的做法将节省很多头痛!