2013-06-12 3 views
0

У меня есть функция:вина Сегментация (strcat_sse2_unaligned) при вызове функции

//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). И Google не помогает много на strcat_sse2_unaligned

EDIT 2

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

'strcat()' не является магическим, вам необходимо выделить ** достаточно большой ** и ** записываемый ** буфер для него. –

+0

Посмотрите на обратную трассу, когда произошел сбой, это делается с помощью команды 'bt' в GDB. Затем перейдите в callstack (используя команду 'up'), пока не придете к вашему коду. Затем изучите там переменные или, по крайней мере, отредактируйте свой вопрос, чтобы показать, где находится ваш код. –

+0

@JoachimPileborg Пожалуйста, взгляните на отредактированный пост. – BaRud

ответ

0

Я считаю, что вы пытаетесь использовать strlen() для вычисления размера буфера, а не длину строки.

Если buffer не содержит действительной строки с 0-символом, вы не можете использовать strlen(). Вероятно, он выйдет из правильной памяти и (что наиболее важно) породит результат, который совсем не то, что вам нужно.

Возможно, у вас должна быть отдельная переменная, удерживающая размер буфера, на который указывает buffer.

2

Я действительно не вижу нигде, где вы выделить память для buffer. Это означает, что это указатель NULL (так как это глобальная переменная). Вы должны выделить память для буфера, прежде чем сможете ее использовать.

0

strcat линия заменена:

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

, который имеет решить эту проблему.

Ждем комментариев.

+0

* t = буфер не выделяет новую память. Он просто заставляет t указывать на буфер. Когда вы освобождаете (t) блок памяти, как и в последней строке, вы фактически освобождаете буфер, который, вероятно, не совсем то, что вы хотите. –

Смежные вопросы