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;
}
答案 0 :(得分:4)
返回return语句中的字符串和将字符串文字分配给本地指针.. 是相同的解决方案。 使用传入的内存池更容易出错,除非您更改函数原型以返回const char*
。
在第三个选项中,将“CHANNEL_IDLE”文字的地址分配给指针类型的局部变量,该值又由值返回。因此,返回原始地址,无论堆栈如何都保持有效(请参阅下面的说明)。选项三与return 0xffffaaaa;
链接器将仔细清除整个代码中定义的字符串文字,并将其重新定位到单个代码部分。根据您的平台,运行时加载器实际上可以将其放入只读内存,写访问可以生成硬件中止。选项一使得返回的字符串修改可行,因为它的副本将位于堆中。从您的用法示例中,我怀疑您是否需要字符串修改,因此'strdup'开销是不必要的。
由于选项二和三是相同的,我会将函数原型更改为返回类型const char*
,并选择其中任何一个。
P.S。 “我们应该忘记小的效率,大约97%的时间说:过早的优化是所有邪恶的根源”D. Knuth