c - 在 Glib 队列中存储结构
问题描述
我有一个错误,其中从 glib 队列中弹出的结构丢失了一些分配的数据。
结构如下:
typedef struct src_file {
off_t size;
int filename;
const char *file_path;
} src_file;
new_src_file()
定义为:
src_file* new_src_file(const char * src_filepath, off_t size, int filename) {
src_file *sh_src_file = malloc(sizeof(src_file));
sh_src_file->file_path = src_filepath;
sh_src_file->size = size;
sh_src_file->filename = filename;
return sh_src_file;
}
这由 nftw 回调函数填充,该回调函数还将对象推送到队列中
src_file *sh_src_file = new_src_file(fpath, statptr->st_size, pfwt->base);
g_queue_push_tail(sh_file_list, sh_src_file);
这个结构包含我们试图用 src_file 结构填充的 Gqueue。sh_file_list
是使用 nftw 所需的全局队列。它被复制到new_src_handler()
typedef struct src_handler {
GQueue* src_list;
off_t src_size;
} src_handler;
src_handler* new_src_handler(char* src_path) {
sh_total = 0;
src_handler *sources = malloc(sizeof(src_handler));
sources->src_list = g_queue_new();
sh_file_list = g_queue_new();
int fd_limit = 5;
int flags = FTW_CHDIR | FTW_DEPTH | FTW_MOUNT | FTW_PHYS;
int ret = nftw(src_path, process, fd_limit, flags);
sources->src_size = sh_total;
sources->src_list = g_queue_copy(sh_file_list);
g_queue_free(sh_file_list);
return sources;
}
通过调试器查看变量表明正在存储结构中的所有信息。
这个队列被另一个函数用来处理存储在其中的文件。我将头从队列中弹出并将其存储在临时 src_file 结构中,file_path 被传递给另一个函数,但它作为“”从队列中出来。
int process(...) {
src_file *src = g_queue_pop_head(copy_job->source_files->src_list);
printf("%.2f\n", src->size);
printf("%d\n", src->filename);
printf("%s\n", src->file_path);
...
return 0;
}
输出:
Scanning Source: /home/user/Downloads/
Total entries: 2
Total Size 128.00
Filename: 23
File Path:
我不明白 file_path 变量发生了什么,为什么它没有正确地从队列中弹出?调试器显示所有数据在被推送到队列时都存在。我做错了什么还是有一些数据被覆盖在内存中?
第一个图像是调试器的输出,就像sh_src_file
被推入队列一样
其次是当它从队列中弹出时。值 12 和 23 结转,但 file_path 是“”,它应该是一个路径。
添加了一些更多的调试消息问题似乎与g_queue_copy()
函数有关,如new_src_handler()
在 nftw 完成其回调函数后发生了一些奇怪的事情中所见。
int process(const char *fpath, const struct stat *statptr, int flags, struct FTW *pfwt) {
if(flags == FTW_F) {
if(strcmp(fpath + pfwt->base, ".DS_Store") != 0) {
src_file *sh_src_file = new_src_file(fpath, statptr->st_size, pfwt->base);
g_queue_push_head(sh_file_list, sh_src_file);
src_file *temp = g_queue_peek_head(sh_file_list);
printf("Pushed %s onto the queue\n", temp->file_path);
sh_total += sh_src_file->size;
}
}
return 0;
}
输出确认这些已被推送到队列中:
Pushed /home/howard/Downloads/test.txt onto the queue
Pushed /home/howard/Downloads/testtwo.txt onto the queue
然而:
src_handler* new_src_handler(char* src_path) {
sh_total = 0;
src_handler *sources = malloc(sizeof(src_handler));
sources->src_list = g_queue_new();
sh_file_list = g_queue_new();
int fd_limit = 5;
int flags = FTW_CHDIR | FTW_DEPTH | FTW_MOUNT | FTW_PHYS;
int ret = nftw(src_path, process, fd_limit, flags);
//re-entry after process()
sources->src_size = sh_total;
//copy global sh_file_list populated by process() to our structure
sources->src_list = g_queue_copy(sh_file_list);
//debugging
src_file *_test = g_queue_peek_head(sources->src_list);
src_file *_gtest = g_queue_peek_head(sh_file_list);
printf("Peeking sh_file_list (global pre-copy) head: %s\n", _gtest->file_path);
printf("Peeking src_list head: %s\n", _test->file_path);
g_queue_clear(sh_file_list);
return sources;
}
输出 process() 中队列中的内容与 new_src_handler() 中查看的内容不同:
Peeking sh_file_list (global pre-copy) head: /home/howard/Downloads
Peeking src_list head: /home/howard/Downloads
解决方案
修改 new_src_handlerg_strdup
解决了这个问题。
推荐阅读
- powerbi - Power bi 计算包含行不工作
- r - R - 如何过滤数据列以显示特定值
- java - 将菜单栏添加到 JFrame 时遇到问题
- react-native - 反应导航获取类组件内的堆栈导航器标题高度(无挂钩)
- wordpress - 我的 wordpress 网站的移动版本有问题
- ios - 从另一个类中的按钮重新加载 UITableView (Swift)
- xml - 如何在 [alfresco] 表单控件中隐藏/显示集合
- json - Angular 使用 RxJS - 当 JSON 对象具有多个属性时如何映射数据
- performance - 如何渲染仅存在于视觉范围内的折线点
- php - 如何在 Symfony 中使用另一个连接执行 Doctrine 迁移?(使用 DoctrineMigrationsBundle 3.0.x)