我正在尝试编写代码

时间:2013-06-22 02:07:25

标签: c

我现在正在做的是一个电话簿管理员,而且我很擅长使用扎实而干净的代码。我想问的是,我做了一个新的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创建者

我最终根据第一个进行了最后两次。

有没有办法可以全面使用第一个并具有最后两个的功能?

1 个答案:

答案 0 :(得分:5)

关于你风格的一些评论:

    #ifdef DEBUG附近不需要
  1. assertassert的重点在于,您可以在#define NDEBUG之前assert.h,然后关闭所有断言。一般情况下,在代码中嵌入#ifdef 任何内容是一种糟糕的风格。如果您需要它,它应该隐藏在定义宏的标题中,以便#ifdef逻辑不会在您的代码中重复 - 与assert.h完全相同的方式。< / p>

  2. 采用void **参数的分配函数被认为是有害的,因为它们鼓励调用者调用未定义的行为。要正确使用此类函数,您必须创建void *类型的变量并将其地址传递给函数。

  3. 例如:

    foo *bar;
    void *tmp;
    flag result = fNewMem(&tmp, sizeof *bar);
    bar = tmp;
    

    这很笨拙,所以每个人都会欺骗并编写以下错误的代码,通过违反别名规则来调用未定义的行为:

    foo *bar;
    flag result = fNewMem((void **)&bar, sizeof *bar);
    

    我会继续说整个函数fNewMem真的没有任何意义。只需使用malloc即可。在一种语言中编写 clean 代码的关键原则之一是学习该语言的习语,而不是试图重新发明它们。