C - g_snprintf 在一种情况下有效,但在另一种情况下无效

C - g_snprintf works in one scenario but not in another

情况很简单。

我有一个指向结构的 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;

然而,当我用另一种方法做基本相同的事情时,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;

从声明中可以看出,error_cause只是一个指针,不是数组。

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

要解决此问题,您需要为字符串分配空间。在 glib-land 中,您可以为此使用漂亮的 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,有人可能会尝试修改字符串,这又会带来未定义的行为。