我现在正在做的是一个电话簿管理员,而且我很擅长使用扎实而干净的代码。我想问的是,我做了一个新的memroy分配函数
flag fNewMem(void** ppv, size_t size)
{
byte** pps = (byte**) ppv;
#ifdef DEBUG
{
assert(ppv != NULL && size != 0);
}
#endif
*pps = (byte*) malloc(size);
#ifdef DEBUG
{
if(*pps != NULL)
memset(*pps, bGarbage, size);
}
#endif
return (*pps != NULL);
}
flag fNewPerInfoMem(perInfo** ppv, size_t size)
{
#ifdef DEBUG
{
assert(ppv != NULL && size != 0);
}
#endif
*ppv = (perInfo*) malloc(size);
#ifdef DEBUG
{
if(*ppv != NULL)
memset(*ppv, bGarbage, size);
}
#endif
return (*ppv != NULL);
}
flag fNewNodeMem(Node** ppv, size_t size)
{
#ifdef DEBUG
{
assert(ppv != NULL && size != 0);
}
#endif
*ppv = (Node*) malloc(size);
#ifdef DEBUG
{
if(*ppv != NULL)
memset(*ppv, bGarbage, size);
}
#endif
return (*ppv != NULL);
}
第一个是基础strcuture,第二个是Linked List
中的Node创建者最后一个是我自己的strcuture创建者
我最终根据第一个进行了最后两次。
有没有办法可以全面使用第一个并具有最后两个的功能?
答案 0 :(得分:5)
关于你风格的一些评论:
#ifdef DEBUG
附近不需要 assert
。 assert
的重点在于,您可以在#define NDEBUG
之前assert.h
,然后关闭所有断言。一般情况下,在代码中嵌入#ifdef
任何内容是一种糟糕的风格。如果您需要它,它应该隐藏在定义宏的标题中,以便#ifdef
逻辑不会在您的代码中重复 - 与assert.h
完全相同的方式。< / p>
采用void **
参数的分配函数被认为是有害的,因为它们鼓励调用者调用未定义的行为。要正确使用此类函数,您必须创建void *
类型的变量并将其地址传递给函数。
例如:
foo *bar;
void *tmp;
flag result = fNewMem(&tmp, sizeof *bar);
bar = tmp;
这很笨拙,所以每个人都会欺骗并编写以下错误的代码,通过违反别名规则来调用未定义的行为:
foo *bar;
flag result = fNewMem((void **)&bar, sizeof *bar);
我会继续说整个函数fNewMem
真的没有任何意义。只需使用malloc
即可。在一种语言中编写 clean 代码的关键原则之一是学习该语言的习语,而不是试图重新发明它们。