我在 gtk 应用程序中有类似的代码(但范围更大):
#include <stdio.h>
struct TStruct {
char *string;
}
void func(struct TStruct *tstruct) {
char chara[8];
sprintf(chara, "%.*s", 4, "testing");
tstruct->string = chara;
}
int main() {
struct TStruct tstruct;
tstruct.string = NULL;
func(&tstruct);
printf("%s", tstruct.string);
return 0;
}
这个片段本身就可以正常工作。然而,在 gtk 应用程序中,在代码片段之后的任何位置创建 gtk 对象都会破坏
tstruct.string
的值。为什么会这样呢?上面的代码片段不是分配字符串的最佳方法吗?tstruct->string = chara
更改为 tstruct->string = g_strdup(chara)
可解决该问题。我可以猜测这就是问题所在,但是有人可以解释一下它是如何工作的吗?
注意。您正在堆栈中分配一个 char 数组,因为它是
func
函数的本地数组,并且它们将其分配给您作为参数传递的 Strike 的成员。我正在为你写一些例子......
这个片段本身就可以正常工作。
不,没有。由于在其生命周期结束后访问对象,它具有未定义的行为。
void func(struct TStruct *tstruct) {
char chara[8];
tstruct->string = chara;
}
此代码(带或不带
sprintf
)存储一个指向局部数组 chara
的第一个元素的指针。函数返回后,chara
的生命周期结束,以后使用访问
printf("%s", tstruct.string)
在对象的生命周期结束后访问该对象。这是未定义的行为。
调用任何
strdup
类型函数都会在空闲存储(在大多数实现中为堆)中分配一个新字符串,其生命周期将持续到显式释放为止,从而使行为得到明确定义。并且您应该释放字符串以避免内存泄漏。