今天照着"Foundations of GTK+ Development"的练习题做了一个exercise2-1,出现如题的错误。我上网搜索了下,
发现都是说环境变量LANG设置的问题,但是我启用中文或者在其它程序里面都没出现这个错误,于是严重怀疑我的代码
出现错误了。先还是贴上代码,让自己出出丑吧,这个错误真该好好记住!
我当时很奇怪(见代码中我的注释),后来在gtk mailing list的各位朋友帮助下才搞明白了:widgets中的标题等属性是由
其类进行分配内存的,如果其中某个部分不使用了,则会自动释放该部分的内存。所以当我调用gtk_window_set_title后,
window的title改变了(复制了textLabel指向的内容),原来的title占用的内存被释放,当我继续调用下面一句gtk_label_
set_text时候,textWindow所指向的已经为空(不一定为空,只是系统给他乱分配了个),乱码当然也就难免啦。哎,悲哀。
只能把那个回调函数修改如下:
可见,GTK 的widgets里面的属性都是由widgets自己掌控的,重新设置的内容也被复制到其内部了。这一点由g_free可以
看出,如果仅仅是用一个指针指向新的内容,那么这里其标题又会不见了吧。
我想,我需要记住的是:GTK中widgets里面的属性都是由widgets自己掌控,不需要的内容都会被widget释放。
如果觉得我解释的不够清楚,请看这位GTK mailing list上的Kristian Rietveld的解释吧:
You have to note that textLabel and
textWindow both point to a string that is internal to the
GtkLabel/GtkWindow widgets. This is why the string has to the const,
you are not allowed to modify that internal string directly. The
point is that when you set another title or text, this internal string
will be replaced with the new string. So as soon as you call
gtk_window_set_title(), the internal title string will be replaced and
after this call your textWindow pointer is no longer valid (because it
points to this internal string that has been replaced). But you still
have to use it for the call to gtk_label_set_text(). Swapping the
calls will not help, because gtk_label_set_text() does the same and
textLabel will become invalid.