2017-04-12 261 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

相關問題