0
gcc 4.7.2
c89

你好,

我有一个函数,它将根据通道的当前状态返回一个字符串。我只是想知道使用什么更好的技术。第一个我使用内存池,以便内存始终有效。第二个只是在 return 语句中返回一个字符串。第三个使用在堆栈上分配的本地指针并返回它。

在所有情况下,我只是打印字符串,不会将其用于其他任何事情。

你会推荐哪一个?

非常感谢您的任何建议,

使用这样的功能:

MODULE_LOG(PRIO_DEBUG, "%s|%s",
        g_channel_state_to_string(channel->previous_state, channel->mem_pool),
        g_channel_state_to_string(channel->current_state, channel->mem_pool));

使用传入的内存池

static char* g_channel_state_to_string(states_e state, apr_pool_t *mem_pool)
{
    char *channel_state = NULL;

    switch(state) {
    case CHANNEL_IDLE:
        channel_state = apr_pstrdup(mem_pool, "CHANNEL_IDLE");
        break;

    default:
        channel_state = apr_pstrdup(mem_pool, "CHANNEL_UNKNOWN_CHANNEL_STATE");
        break;
    }

    return channel_state;
}

在 return 语句中返回字符串

static char* g_channel_state_to_string(states_e state)
{  
    switch(state) {
    case CHANNEL_IDLE:
        return "CHANNEL_IDLE";
        break;

    default:
        return "CHANNEL_UNKNOWN_CHANNEL_STATE";
        break;
    }
}

将字符串文字分配给本地指针可能会导致堆栈转储,因为内存是在堆栈上分配的,并且在函数返回时可能不存在。

static char* g_channel_state_to_string(states_e state)
{
    char *channel_state = NULL;

    switch(state) {
    case CHANNEL_IDLE:
        channel_state = "CHANNEL_IDLE";
        break;

    default:
        channel_state = "CHANNEL_UNKNOWN_CHANNEL_STATE";
        break;
    }

    return channel_state;
}
4

1 回答 1

4

在 return 语句中返回字符串并将字符串文字分配给本地指针..是相同的解决方案。使用传入的内存池更容易出错,除非您将函数原型更改为 return const char*

在第三个选项中,您将“CHANNEL_IDLE”字面量的地址分配给指针类型的局部变量,该变量进一步按值返回。因此,原始地址被返回,无论堆栈如何,它都保持有效(参见下面的解释)。选项三与return 0xffffaaaa;

在整个代码中定义的字符串文字将被链接器仔细清除并重新定位到单个代码段中。根据您的平台,运行时加载程序实际上可以将其放入只读内存,并且写入访问可以生成硬件中止。选项一使返回的字符串修改可行,因为它的副本将位于堆中。从您的使用示例中,我怀疑您是否想要修改字符串,因此“strdup”开销是不必要的。

由于选项二和三是相同的,我会将函数原型更改为返回类型为const char*并选择其中任何一个。

PS“我们应该忘记小的效率,说大约 97% 的时间:过早优化是万恶之源” D. Knuth

于 2013-02-22T08:39:07.820 回答