c - 通过从二进制文件中加载结构数据并加载到 C 中的 gtk 列表存储中,出现内存问题

标签 c pointers struct gtk

我的 GTK 程序存在内存问题,但我不知道如何修复它。 当我关闭程序时,程序列表存储中的数据使用 fwrite 保存在二进制文件中。该代码似乎可以工作:

void on_window_destroy (GtkWidget *object, gpointer user_data)  
{   
  gint i;
  GtkTreeIter   iter;
  GtkTreeModel *model = GTK_TREE_MODEL(gtk_builder_get_object (builder,"liststore"));
  gint n_rows   = gtk_tree_model_iter_n_children( model, NULL ); //count the rows
  FILE *pfile   = fopen("Data", "wb" );
  gtk_tree_model_get_iter_first (model, &iter);//set iter postion to the first row    
 data *pdata = malloc(sizeof(data));
 for (i = 0 ; i < n_rows; i++)
 {
    gtk_tree_model_get (model, &iter, 
    SPALTE_ArtName, &pdata->ArtBez,
    SPALTE_ArtNr,   &pdata->ArtNr,
    SPALTE_LBest,   &pdata->LBest,
    -1);
    //just to check the data 
    g_printf("Zeile %d: %s | %d | %d\n",i, pdata->ArtBez, pdata->ArtNr, pdata->LBest);
    fwrite(pdata,sizeof(data),1,pfile);
    gtk_tree_model_iter_next (model, &iter); //iter = next row
 }
 free(pdata);
 fclose(pfile);
 g_printf("Saved successfully!\n\n");

 gtk_main_quit();
}

此后,当我再次启动程序时,它应该使用 fread 读取二进制文件并将数据添加到空列表存储中 我尝试过这样的:

data *pdata = malloc (sizeof(data));
FILE *pfile = fopen("Data","rb");
if (pfile == NULL)
{
  g_printf("Error: Data File not Found! Creating new list....\n");
}
else
{  
while (fread (pdata,sizeof(data),1,pfile))
{
  g_printf("Test 1 \n\n\n");
  gtk_list_store_append(GTK_LIST_STORE(model), &iter); //add new row
  g_printf("Test 1 \n\n\n");
  gtk_list_store_set (GTK_LIST_STORE(model), &iter,
                      SPALTE_ArtName,pdata->ArtBez,
                      SPALTE_ArtNr,pdata->ArtNr,
                      SPALTE_LBest,pdata->LBest,
                      -1);
}

free(pdata);
fclose(pfile);
} 

这是 pdata 中使用的数据结构:

 typedef struct _data
{
 gchar *ArtBez;
 gint   *ArtNr;
 gint   *LBest;
}data;

这个问题肯定与 pdata->ArtBez 有关,因为当我将其选中时,它工作正常。
编辑:
在我将答案从斯塔克(非常感谢!)中红色化后,我将“数据”结构更改为没有指针的结构

typedef struct _data
{
 gchar ArtBez[128];
 gint   ArtNr;
 gint   LBest;
}data;

然后我将上面的写入函数更改为:

 void on_window_destroy (GtkWidget *widget, gpointer user_data)
{
gint i, *BufArtNr, *BufLBest;
gchar *BufArtBez;
GtkTreeIter   iter;
GtkTreeModel *model = GTK_TREE_MODEL(gtk_builder_get_object (builder, "liststore")); //Hole liststore aus glade-Datei
gint n_rows     = gtk_tree_model_iter_n_children( model, NULL ); //count rows
FILE *pfile     = fopen("Data", "wb" );
gtk_tree_model_get_iter_first (model, &iter); //Zeiger auf erste Zeile setzen
data *pdata = malloc(sizeof(data)*n_rows);

for (i = 0 ; i < n_rows; i++) //For every row
{
  gtk_tree_model_get (model, &iter, //Get data from row
    SPALTE_ArtNr,   &BufArtNr, 
    SPALTE_ArtBez,  &BufArtBez,
SPALTE_LBest,   &BufLBest,
    -1);
  //Schreibe Daten in Struct
  pdata[i].ArtNr  = BufArtNr;
  strcpy(pdata[i].ArtBez, BufArtBez);
  pdata[i].LBest  = BufLBest;

  fwrite(&pdata[i],sizeof(data),1,pfile); //Write data to file
  gtk_tree_model_iter_next (model, &iter); //Next row
}
free(pdata);free(BufArtBez);
fclose(pfile);      
g_printf("Saved successfully\n\n");
}

这可行,但是当我编译程序时,编译器会收到警告:

 warning: assignment makes integer from pointer without a cast [enabled by default]
   pdata[i].ArtNr  = BufArtNr;

pdata[i].LBest = BufLBest; 具有相同的警告
我的错误在哪里?

最佳答案

pdata仅包含指针,对于保存和恢复没有用处。而不是

fwrite(pdata,sizeof(data),1,pfile);

你需要做

fwrite(pdata->ArtBez,...
fwrite(pdata->ArtNr,...
fwrite(pdata->LBest,...

然后当你读回它们时构建一个新的结构。

关于c - 通过从二进制文件中加载结构数据并加载到 C 中的 gtk 列表存储中,出现内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28701254/

相关文章:

c - Erlang 中的 AES-256/CBC 加密和 C 中的解密不起作用

c - 一个奇怪的段错误

c - 有没有办法在循环中打印结构成员而无需在 C 中命名每个成员?

c - 在 C 错误消息中返回结构体数据类型

c - 从 Sun C 编译器迁移到 gcc

c - NGINX 中的模块链接

c - 指向同一堆区域的随机地址的双指针

c - 返回指向数组中最大数的指针的函数

c - 为什么浮点变量的地址及其指针不会产生相同的结果?

c - 对 struct tm 的数组进行排序