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

C-g_snprintf在一种场景中工作,但在另一种场景中不工作,c,glib,C,Glib,情况很简单 我有一个指向struct的响应指针,我想填充它的值 在一个地方它起作用了: 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->err

情况很简单

我有一个指向struct的
响应
指针,我想填充它的值

在一个地方它起作用了:

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\u 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语言中,做这类事情的最佳实践是什么

谢谢

编辑:更奇怪的是,当我编辑时:

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\u cause
只是一个指针,而不是数组

因此,当您分配(并清除)janus\u audiobridge\u sync\u endpoint\u response的实例时,它不会指向任何有效的对象。因此,您会得到未定义的行为

要解决此问题,需要为字符串分配空间。在glib land中,您可以使用nice功能来实现此目的:

response->error_cause = g_strdup_printf("%s - %s", "Failed to find about page with locale - ", "foo", locale_text);
请注意,我在该调用中添加了一个
foo
,考虑到格式字符串,您的原始代码似乎无法提供正确数量的参数,这(同样!)会给您带来未定义的行为


例如,执行
错误\u cause=“hello”
总是比较安全的,因为它只是将结构中的指针设置为指向内存中某个位置的静态数组,它不会复制任何字符。唯一的风险是,由于结构中的指针不是常量,因此可能有人试图修改字符串,这将再次带来未定义的行为。

从声明中可以清楚地看出,
error\u cause
只是一个指针,而不是数组

因此,当您分配(并清除)janus\u audiobridge\u sync\u endpoint\u response的实例时,它不会指向任何有效的对象。因此,您会得到未定义的行为

要解决此问题,需要为字符串分配空间。在glib land中,您可以使用nice功能来实现此目的:

response->error_cause = g_strdup_printf("%s - %s", "Failed to find about page with locale - ", "foo", locale_text);
请注意,我在该调用中添加了一个
foo
,考虑到格式字符串,您的原始代码似乎无法提供正确数量的参数,这(同样!)会给您带来未定义的行为


例如,执行
错误\u cause=“hello”
总是比较安全的,因为它只是将结构中的指针设置为指向内存中某个位置的静态数组,它不会复制任何字符。这样做的唯一风险是,由于结构中的指针不是常量,因此可能有人试图修改字符串,这将再次带来未定义的行为。

显示
janus\u audiobridge\u sync\u endpoint\u response的定义。
;还有可能是一个。@Evert嘿,Evert!我更新了我的问题。所以,如果你在
goto-plugin\u-response
上放置一个断点,
response->error\u-cause
就在那里是空的?当我尝试在
g\u-snf下面记录
response->error\u-cause
时(response…
行。为空。显示
janus\u audiobridge\u sync\u endpoint\u response
的定义,可能还有一个。@Evert嘿,Evert!我更新了我的问题。因此,如果你在
转到插件\u response
上放置一个断点,
response->error\u cause
就在那里为空?当我尝试记录
响应->错误\u cause
就在
g\u snprintf(response…
行下面。它是空的。我想我不明白。为什么在第一个示例中它能工作?解决方案是什么?@IvRRimUm:它第一次工作时是偶然的,指针没有指向分配的缓冲区。@IvRRimUm它不“工作”,它只是没有以你注意到的方式失败。未定义的行为是未定义的,它可能会做你期望的事情,但仍然是错误的。另一个问题。为什么我必须在一种情况下分配内存,而不是在直接赋值中分配内存?@IvRRimUm我确实谈到了这一点,见最后一段。我想我不明白。为什么它在第一段中有效那么,示例?解决方案是什么?@IvRRimUm:它在第一次工作时是偶然的,指针没有指向分配的缓冲区。@IvRRimUm它不“工作”,它只是没有以你注意到的方式失败。未定义的行为是未定义的,它可能会做你期望的事情,但仍然是错误的。另一个问题。为什么我必须在一种情况下分配内存,而不是在直接赋值中分配内存?@IvRRimUm我确实谈到了这一点,见最后一段。