为什么会出现分段错误?

时间:2013-05-20 21:30:03

标签: c++ gtk char

我的GTK计划仍然存在问题。

当我单击编码(或解码)按钮时,我收到错误消息:

  

分段错误

我认为问题来自于功能:retencode,但无法找到。

    //..
    //gets the first argument(buf)
    tx1=gtk_entry_get_text(GTK_ENTRY(entry));
    //...
    //gets the second argument(pass)
    tx2=gtk_entry_get_text(GTK_ENTRY(entry));
    //....
    //signal to callback function encode when button clicked
    g_signal_connect(but,"clicked",G_CALLBACK(encode(tx1,tx2)),NULL);
    // ...
    //convert const char* to char*
    char* ret (const char *bd){
    char *c = new char[12];
    strcpy(c,bd);
    return c;
} 

//encode function
char encode(const char ebuf[],const char epass[]) {
    //This is the complete function I wrote and I am still having the error.
    char *buf=ret(ebuf);
    char *pass=ret(epass);
}

2 个答案:

答案 0 :(得分:1)

这条线毫无意义:

g_signal_connect(but,"clicked",G_CALLBACK(encode(tx1,tx2)),NULL);

您正在使用一些参数调用encode(),它会返回char值,(顺便说一下是未定义的),然后将char投射到GCallback,即指向函数的指针。然后,当点击按钮时,Gtk +会尝试调用你的char,这显然不是一个有效的函数,因此会出现分段错误。

不确定你想做什么,但你必须玩by the rules,并且规则说"clicked"回调应该是这个原型的指向函数的指针:

void f(GtkButton *button, gpointer user_data);

除此之外,你玩的很危险。

示例代码

比方说,例如,您希望以encode作为参数调用函数char*。你可以这样做:

void clicked_encode(GtkButton *button, gpointer user_data)
{
    char *d = static_cast<char*>(user_data);
    encode(d);
}

并注册回调

g_signal_connect(but, "clicked", G_CALLBACK(clicked_encode), text);

这假设text指向的内存至少与回调一样长。如果情况并非如此,那么你可以复制一份,但是你必须记得将它释放出来:

char *d = strdup(text);
g_signal_connect_data(but, "clicked", G_CALLBACK(clicked_encode), d, free_text, 0);

//and the deleter function
void free_text(gpointer *data, GClosure *)
{
    char *d = static_cast<char*>(data);
    free(d);
}

当然,您的函数可能需要多个参数,但只能传递一个指针。解决方案是定义一个结构(或一个类,你正在使用C ++),其中包含所有内容:

FancyClass *d = new FancyClass(...);
g_signal_connect_data(but, "clicked", G_CALLBACK(clicked_encode), d, free_fancy_class, 0);

void clicked_encode(GtkButton *button, gpointer user_data)
{
    FancyClass *d = static_cast<FancyClass*>(user_data);
    encode(d);
}

void free_fancy_class(gpointer *data, GClosure *)
{
    FancyClass *d = static_cast<FancyClass*>(data);
    delete d;
}

喂!您甚至可以使encode()成为FancyClass的成员函数。可能性无穷无尽!

我希望这会让你走上正轨......

答案 1 :(得分:0)

如果您不想拥有更多动态大小的字符串,请使用strncpy来限制要复制的字符数。