在 Glib 队列中存储结构
Storing structs in Glib Queues
我有一个错误,从 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_handler 修改为 g_strdup
解决了问题。
我有一个错误,从 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_handler 修改为 g_strdup
解决了问题。