2017-04-12 171 views
0

非常简单的情况。C - g_snprintf在一种情况下工作,但不在另一种情况下工作

我有一个response结构指针,我想填充它的值。

在一个。安迪它的工作:

janus_audiobridge_sync_endpoint_response *response = g_malloc0(sizeof(janus_audiobridge_sync_endpoint_response)); 
response->error_code = JANUS_AUDIOBRIDGE_ERROR_UNKNOWN_ERROR; 
g_snprintf(response->error_cause, 512, "%s - %s", "Failed to find about page with locale - ", locale_text); 
return response; 

但是当我这样做basicly同样的事情的另一种方法,将response->error_cause原来是null

janus_audiobridge_sync_endpoint_response *response = g_malloc0(sizeof(janus_audiobridge_sync_endpoint_response)); 
response->error_code = 0; 
response->error_code = JANUS_AUDIOBRIDGE_ERROR_UNAUTHORIZED; 
g_snprintf(response->error_cause, 512, "You need to pass a valid user_secret, before you continue."); 
goto plugin_response; 

我的问题:为什么它的工作原理在一种情况下,而不是另一种? C中最好的Practive是做什么的?

谢谢!

编辑:甚至离奇的是,当我这样做:

response->error_cause = "You need to pass a valid user_secret, before you continue."; 

它可以在第二个例子中,这是为什么?

编辑:

按照要求:

typedef struct janus_audiobridge_sync_endpoint_response { 
    gint error_code; 
    gchar *error_cause; 
    json_t *message; 
} janus_audiobridge_sync_endpoint_response; 
+0

显示'janus_audiobridge_sync_endpoint_response'的定义;并可能是[MCVE]。 – Evert

+0

@Evert嘿Evert!我更新了我的问题。 – IvRRimUm

+0

因此,如果你在'goto plugin_response'上放置了一个断点,那么'response-> error_cause'在那里是空的? – Lou

回答

3

这是从声明清楚地表明error_cause只是一个指针,而不是一个数组。

因此,当您分配(并清除)janus_audiobridge_sync_endpoint_response的实例时,它不会指向任何有效的内容。因此你得到未定义的行为。

要解决这个问题,您需要为字符串分配空间。在巧舌如簧,土地,你可以使用这个漂亮的g_strdup_printf()功能:

response->error_cause = g_strdup_printf("%s - %s", "Failed to find about page with locale - ", "foo", locale_text); 

注意,我添加了一个foo这一号召,你原来的代码似乎不能提供的考虑格式字符串参数的正确数量,哪(再次!)给你未定义的行为。

做例如error_cause = "hello";始终是一种安全的方式,因为它只是将结构中的指针设置为指向内存中某个静态数组,而不会复制任何字符。唯一的风险是由于结构中的指针不是const,有人可能会尝试修改字符串,这又会带来未定义的行为。

+0

我不认为我理解。为什么它在第一个例子中工作呢?是解决方案吗? – IvRRimUm

+0

@IvRRimUm:它第一次意外工作,指针没有指向分配的缓冲区 – Lou

+0

@IvRRimUm它没有“工作”,它只是未能以您注意到的方式失败。行为是不确定的,它可能做你期望的确切的事情,但仍然是错误的。 – unwind

相关问题