我正在尝试实现表示文件夹树的链表数据结构。
以下结构:
typedef struct SRC_ERROR SRC_ERROR;
struct SRC_ERROR {
int error_code;
char *error;
};
typedef struct SRC_FILE SRC_FILE;
struct SRC_FILE {
char *entry;
char md5[MD5_DIGEST_LENGTH];
};
typedef struct SRC SRC; //Source file tree with md5 entry char for source verification.
struct SRC {
SRC_ERROR error;
char *name;
char *full_path;
SRC_FILE **entries;
SRC *next_dir;
};
想法是每个目录都将存储在SRC
中,SRC_FILE
用作存储每个文件的文件名和md5值的数组。
下面的scan_source()
填充结构。
SRC *scan_source(char *source_path) {
SRC* source = malloc(sizeof(SRC));
source->error.error_code = OK;
int count = 0;
DIR *dir;
struct dirent *entry;
if(!(dir = opendir(source_path))) {
source->error.error_code = ERROR;
source->error.error = "Unable to open source directory.\n";
return source;
}
source->entries = (SRC_FILE **) malloc(sizeof(SRC_FILE*) * count);
if(source->entries == NULL) {
source->error.error_code = ERROR;
source->error.error = "Unable to allocate memory to file entry tree\n";
}
while((entry = readdir(dir)) != NULL ) {
if(entry->d_type == DT_DIR) {
char path[PATH_MAX];
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
snprintf(path, sizeof(path), "%s/%s", source_path, entry->d_name);
printf("[%s] - %s\n", entry->d_name, path);
//add new node
source = add_dir(source, insert_dir_node(entry->d_name, path));
scan_source(path);
}
else if (entry->d_type == DT_REG) {
printf("[FILE] - %s\n", entry->d_name);
source->entries[count]->entry = entry->d_name; //SEGFAULT HERE
count++;
source->entries = realloc(source->entries, sizeof(SRC_FILE*)*(count));
}
}
closedir(dir);
return source;
}
我在内存管理方面遇到问题。当目录以某些方式构造时,我会遇到间歇性的段错误。
我已标记调试器已标记的行
source->entries[count]->entry = entry->d_name; //SEGFAULT HERE
我以为我为每种结构分配了内存,但是也许我没有正确地做到这一点,或者数据结构完全存在潜在的问题?
例如:
test> tree
.
└── Text
0 directories, 1 file
这会导致段故障。而这不是:
/test> tree
.
├── another sample
│ └── Text
└── sample folder
2 directories, 1 file
使用的附加功能:
SRC *add_dir(SRC *file_tree, SRC *new_dir) {
new_dir->next_dir = file_tree;
return new_dir;
}
SRC *insert_dir_node(char *name, char *full_path) {
SRC *next_dir;
next_dir = (SRC *) emalloc(sizeof(SRC));
next_dir->name = name;
next_dir->full_path = full_path;
next_dir->next_dir = NULL;
return next_dir;
}
[我开始看代码,看到的第一个问题是您存储的是readdir()
调用返回的指针-您应该复制其中包含的数据。
更改
source = add_dir(source, insert_dir_node(entry->d_name, path));
to
source = add_dir(source, insert_dir_node(strdup(entry->d_name), path));
看到分段错误的原因是,您总是在source->entries
数组的结尾之后写。
您最初创建一个大小为0的数组:
int count = 0;
/* ... */
source->entries = (SRC_FILE **) malloc(sizeof(SRC_FILE*) * count);
然后设置其第一个(索引为0)元素:
source->entries[count]->entry = entry->d_name; //SEGFAULT HERE
count++;
source->entries = realloc(source->entries, sizeof(SRC_FILE*)*(count));
然后将数组扩展为1个元素,然后写入第二个索引,依此类推。
您可以固定逻辑(总是为count+1
元素分配空间,因为您不仅要为现有元素分配空间,而且还希望为下一个元素分配空间),或者在这种情况下可能更有效,切换到这里的链接列表结构。