返回函数中的字符串

时间:2013-02-22 08:10:01

标签: c optimization

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;
}

1 个答案:

答案 0 :(得分:4)

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

在第三个选项中,将“CHANNEL_IDLE”文字的地址分配给指针类型的局部变量,该值又由值返回。因此,返回原始地址,无论堆栈如何都保持有效(请参阅下面的说明)。选项三与return 0xffffaaaa;

相同

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

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

P.S。 “我们应该忘记小的效率,大约97%的时间说:过早的优化是所有邪恶的根源”D. Knuth