C - g_snprintf在一个场景中工作,但在另一个场景中不工作

时间:2017-04-12 10:55:10

标签: c glib

非常简单的情况。

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

1 个答案:

答案 0 :(得分:3)

从声明中可以清楚地看出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,有人可能会尝试修改字符串,这会再次带来未定义的行为。