【问题标题】:Segmentation fault (strcat_sse2_unaligned) while calling a function调用函数时出现分段错误 (strcat_sse2_unaligned)
【发布时间】:2013-06-12 06:02:01
【问题描述】:

我有一个函数:

//In main.c    
char output_entry () {
  extern  FILE* yyin;
  extern int yyparse (void);
  yyin=fmemopen(buffer,strlen(buffer),"r");
  return yyparse();
}

调用时效果很好
//Open file
gchar *filename;
void open_file(GtkWidget *widget, gpointer data)
{
  GError* error=NULL;
  GtkWidget *dialog;
  GtkFileFilter *filter;
  dialog = gtk_file_chooser_dialog_new("Open File", NULL,
      GTK_FILE_CHOOSER_ACTION_OPEN,
      GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
      NULL);
  filter = gtk_file_filter_new();
  gtk_file_filter_set_name(filter, "All files (*.*)");
  gtk_file_filter_add_pattern(filter, "*");
  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);

  filter = gtk_file_filter_new();
  gtk_file_filter_set_name(filter, "Bibtex file (*.bib)");
  gtk_file_filter_add_pattern(filter, "*.bib");
  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
  gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);

  if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
  {
    gtk_list_store_clear (store);
    filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
    g_file_get_contents(filename, &buffer, &length , &error);
    g_assert(!error);
    buf_mod=FALSE;

    char* markup=g_markup_printf_escaped ("<span style=\"italic\">%s</span>", filename);
    gtk_label_set_markup(GTK_LABEL(flabel), markup);
    gtk_widget_destroy(dialog); 

    output_entry();
  }
  else{
    gtk_widget_destroy(dialog);
//    g_free(buffer);
  }
}

这是打开文件的标准方法。 buffer

//in main.h
extern gchar *buffer; 

并在 main.c 中初始化(建议 here

这部分代码运行良好。 我也尝试将 output_entry 与其他一些来源一起使用:

void gs_open(GtkWidget *window, gpointer data) {
  GScanner *gs_scanner;
  GHashTable *gs_table;
  GError* error=NULL;
  GtkTextIter start, end;
  GtkListStore *gs_store;
  GtkTreeIter siter;
  GtkWidget *gs_tree;
  gboolean valid;
  GString *ustring = g_string_new ("");
  GString *str=g_string_new(NULL);

  GtkTextBuffer *gs_buf=gtk_text_view_get_buffer(GTK_TEXT_VIEW(gs_txt));
  gtk_text_buffer_get_start_iter (gs_buf, &start);
  gtk_text_buffer_get_end_iter (gs_buf, &end);
  gchar *gs_text = gtk_text_buffer_get_text (gs_buf, &start, &end, FALSE);
  strcat(buffer, gs_text);
  gtk_list_store_clear(store);
  output_entry ();
  buf_mod=TRUE;
  gtk_widget_destroy(gtk_widget_get_toplevel (window));
}

这会导致段错误。运行 gdb 显示:

Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7ffff16fc700 (LWP 6178)]

Program received signal SIGSEGV, Segmentation fault.
0x0000003b94097261 in __strcat_sse2_unaligned () from /lib64/libc.so.6

请帮助(我是 C 新手)。谷歌对strcat_sse2_unaligned的帮助不大

编辑 2

 up
#1  0x0000000000407195 in gs_open (window=0x863a80, data=<optimized out>)
    at src/search.c:103
103   strcat(buffer, gs_text);

【问题讨论】:

  • strcat() 并不神奇,你需要为它分配一个足够大可写的缓冲区。
  • 查看崩溃发生时的回溯,使用 GDB 中的bt 命令完成。然后走上调用堆栈(使用up 命令),直到找到您的代码。然后检查那里的变量,或者至少编辑您的问题以显示代码中的位置。
  • @JoachimPileborg 请查看已编辑的帖子。
  • buffer 是指向目标数组的指针,它应该包含一个 C 字符串,并且足够大以包含连接的结果字符串。
  • 我不明白,但我怀疑buffer 的大小是否是这里的问题。我可以使用open_file 打开a.txt,它是8KB,但是在尝试使用gs_open 打开b.txt 这是4KB 时出现下垂错误

标签: c gtk strcat


【解决方案1】:

我真的没有看到您为buffer 分配内存的任何地方分配。这意味着它是一个NULL 指针(因为它是一个全局变量)。您必须先为缓冲区分配内存,然后才能使用它。

【讨论】:

    【解决方案2】:

    我相信您正在尝试使用 strlen() 来计算缓冲区的大小,而不是字符串的长度。

    如果buffer 不包含有效的以0 结尾的字符串,则不能对其使用strlen()。它可能会超出有效内存,并且(最重要的是)生成完全不是您需要的结果。

    您可能应该有一个单独的变量来保存buffer 指向的缓冲区的大小。

    【讨论】:

      【解决方案3】:

      strcat 行被替换为:

        if (buffer == NULL){
          buffer=g_strdup(gs_text);
        }
        else{
          gchar *t=buffer;
          buffer=g_strconcat(buffer,gs_text,NULL);
          g_free(t);
        }
      

      解决了这个问题。

      期待cmets。

      【讨论】:

      • *t = 缓冲区未分配新内存。它只是使 t 指向缓冲区。当您像在最后一行中那样释放(t)内存块时,实际上是在释放缓冲区,这可能不是您想要的。
      猜你喜欢
      • 2011-01-08
      • 1970-01-01
      • 2018-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多