从函数返回的 GtkWidget* 导致分段错误
GtkWidget* returned from a function lead to segmentation fault
我在问为什么如果我决定调用另一个文件中的函数,如果使用返回的 GtkWidget* 将导致分段错误(强制转换,示例中的 gtk 函数,...)
这里是 main I 运行 gtk_init 并尝试 GTK_IS_WIDGET 从另一个文件中定义的函数
main.c
#include <gtk/gtk.h>
#include <glib.h>
int main(){
gtk_init(NULL, NULL);
GTK_IS_WIDGET(new_widget());
}
在另一个文件中,我创建了一个新的 GtkWidget 并使用函数 GTK_IS_WIDGET,然后我打印一个 "OK" 以了解执行是否到达此点
extern_file.c
#include<gtk/gtk.h>
GtkWidget* new_widget(){
GtkWidget *new = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GTK_IS_WIDGET(new);
g_print("OK\n");
return new;
}
我这样编译两个文件gcc -o main.o main.c esterno.c $(pkg-config --cflags --libs glib-2.0 gtk+-2.0)
我收到很多警告,(我把它们放在那里)但没有错误。
main.c:6:17: warning: implicit declaration of function ‘new_widget’ [-Wimplicit-function-declaration]
GTK_IS_WIDGET(new_widget());
^
/usr/include/glib-2.0/gobject/gtype.h:2238:44: note: in definition of macro ‘_G_TYPE_CIT’
GTypeInstance *__inst = (GTypeInstance*) ip; GType __t = gt; gboolean __r; \
^~
/usr/include/gtk-2.0/gtk/gtkwidget.h:139:35: note: in expansion of macro ‘G_TYPE_CHECK_INSTANCE_TYPE’
#define GTK_IS_WIDGET(widget) (G_TYPE_CHECK_INSTANCE_TYPE ((widget), GTK_TYPE_WIDGET))
^~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:6:3: note: in expansion of macro ‘GTK_IS_WIDGET’
GTK_IS_WIDGET(new_widget());
^~~~~~~~~~~~~
/usr/include/glib-2.0/gobject/gtype.h:2238:27: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
GTypeInstance *__inst = (GTypeInstance*) ip; GType __t = gt; gboolean __r; \
^
/usr/include/glib-2.0/gobject/gtype.h:495:66: note: in expansion of macro ‘_G_TYPE_CIT’
#define G_TYPE_CHECK_INSTANCE_TYPE(instance, g_type) (_G_TYPE_CIT ((instance), (g_type)))
^~~~~~~~~~~
/usr/include/gtk-2.0/gtk/gtkwidget.h:139:35: note: in expansion of macro ‘G_TYPE_CHECK_INSTANCE_TYPE’
#define GTK_IS_WIDGET(widget) (G_TYPE_CHECK_INSTANCE_TYPE ((widget), GTK_TYPE_WIDGET))
^~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:6:3: note: in expansion of macro ‘GTK_IS_WIDGET’
GTK_IS_WIDGET(new_widget());
如果我 运行 文件 (./main.o
) 我收到 "OK" 消息确认函数内部的 GTK_IS_WIDGET 工作正常,但随后出现分段错误当在 main.
中调用 GTK_IS_WIDGET 时
如果我在 main 中声明函数一切正常,但这不是真正的解决方案。
提前致谢
I get many warnings, (Which I put down there) but no error.
对于 C 来说,这是一种危险的心态,任何警告都绝对是致命的。我建议在开发时将 -Wall
与 gcc 一起使用(并且只针对特定情况放宽)。
在这种情况下,编译器会这样警告您:
main.c:6:17: warning: implicit declaration of function ‘new_widget’
在 C 中,这意味着在调用您的函数时会使用 int new_widget()
的默认签名。您的实际函数签名当然与此不匹配,所以不好的事情开始发生。
您可以通过添加包含正确函数签名的头文件并在您的 main.c.
中 #include 该头文件来解决此问题
我在问为什么如果我决定调用另一个文件中的函数,如果使用返回的 GtkWidget* 将导致分段错误(强制转换,示例中的 gtk 函数,...)
这里是 main I 运行 gtk_init 并尝试 GTK_IS_WIDGET 从另一个文件中定义的函数
main.c
#include <gtk/gtk.h>
#include <glib.h>
int main(){
gtk_init(NULL, NULL);
GTK_IS_WIDGET(new_widget());
}
在另一个文件中,我创建了一个新的 GtkWidget 并使用函数 GTK_IS_WIDGET,然后我打印一个 "OK" 以了解执行是否到达此点
extern_file.c
#include<gtk/gtk.h>
GtkWidget* new_widget(){
GtkWidget *new = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GTK_IS_WIDGET(new);
g_print("OK\n");
return new;
}
我这样编译两个文件gcc -o main.o main.c esterno.c $(pkg-config --cflags --libs glib-2.0 gtk+-2.0)
我收到很多警告,(我把它们放在那里)但没有错误。
main.c:6:17: warning: implicit declaration of function ‘new_widget’ [-Wimplicit-function-declaration]
GTK_IS_WIDGET(new_widget());
^
/usr/include/glib-2.0/gobject/gtype.h:2238:44: note: in definition of macro ‘_G_TYPE_CIT’
GTypeInstance *__inst = (GTypeInstance*) ip; GType __t = gt; gboolean __r; \
^~
/usr/include/gtk-2.0/gtk/gtkwidget.h:139:35: note: in expansion of macro ‘G_TYPE_CHECK_INSTANCE_TYPE’
#define GTK_IS_WIDGET(widget) (G_TYPE_CHECK_INSTANCE_TYPE ((widget), GTK_TYPE_WIDGET))
^~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:6:3: note: in expansion of macro ‘GTK_IS_WIDGET’
GTK_IS_WIDGET(new_widget());
^~~~~~~~~~~~~
/usr/include/glib-2.0/gobject/gtype.h:2238:27: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
GTypeInstance *__inst = (GTypeInstance*) ip; GType __t = gt; gboolean __r; \
^
/usr/include/glib-2.0/gobject/gtype.h:495:66: note: in expansion of macro ‘_G_TYPE_CIT’
#define G_TYPE_CHECK_INSTANCE_TYPE(instance, g_type) (_G_TYPE_CIT ((instance), (g_type)))
^~~~~~~~~~~
/usr/include/gtk-2.0/gtk/gtkwidget.h:139:35: note: in expansion of macro ‘G_TYPE_CHECK_INSTANCE_TYPE’
#define GTK_IS_WIDGET(widget) (G_TYPE_CHECK_INSTANCE_TYPE ((widget), GTK_TYPE_WIDGET))
^~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:6:3: note: in expansion of macro ‘GTK_IS_WIDGET’
GTK_IS_WIDGET(new_widget());
如果我 运行 文件 (./main.o
) 我收到 "OK" 消息确认函数内部的 GTK_IS_WIDGET 工作正常,但随后出现分段错误当在 main.
如果我在 main 中声明函数一切正常,但这不是真正的解决方案。
提前致谢
I get many warnings, (Which I put down there) but no error.
对于 C 来说,这是一种危险的心态,任何警告都绝对是致命的。我建议在开发时将 -Wall
与 gcc 一起使用(并且只针对特定情况放宽)。
在这种情况下,编译器会这样警告您:
main.c:6:17: warning: implicit declaration of function ‘new_widget’
在 C 中,这意味着在调用您的函数时会使用 int new_widget()
的默认签名。您的实际函数签名当然与此不匹配,所以不好的事情开始发生。
您可以通过添加包含正确函数签名的头文件并在您的 main.c.
中 #include 该头文件来解决此问题