当我尝试访问使用 malloc
获取的内存中的数据时,数据已损坏
我正在编写一个程序,它读取 Linux 目录并将文件和子目录的名称写入“字符串数组”(c 中的 char** 数组)。它使用 dirent.h
功能运行,例如 readdir()
。 readdir 返回一个 dirent 结构,该结构具有 dname[256]
,这是目标目录中文件/子目录的名称。我将 dirent string(char*) 等同于 char** 数组中 malloced 位置的索引
我基本上有一个 walk_path()
函数,它读取目录条目并将它们的名称写入分配的位置,然后返回该位置
data_t* walk_path(char* path) {
int size = 0;
if(path == NULL){
printf("NULL path\n");
return NULL;
}
struct dirent* entry;
DIR* dir_l = opendir(path);
if(dir_l == NULL) {
char** data = (char**)malloc(sizeof(char*) * 2);
data[0] = path;
data_t* ret = (data_t*)malloc(sizeof(data_t));
ret->data = data;
ret->size = 1;
return ret;
}
while((entry = readdir(dir_l)) != NULL) {
if(!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
continue;
size++;
}
closedir(dir_l);
char** data = (char**)malloc(sizeof(char*) * size + 1);
int loop_v = 0;
dir_l = opendir(path);
while((entry = readdir(dir_l)) != NULL && loop_v < size) {
if(!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
continue;
data[loop_v] = entry->d_name;
loop_v++;
}
closedir(dir_l);
data_t* ret = (data_t*)malloc(sizeof(data_t*));
ret->size = (size_t)size;
ret->data = data;
return ret;
}
和一个合并路径函数,它可以接受两个目录并将它们的数据写入一个数组
char** merge_path(char* path, char* path2) {
data_t* path_data = walk_path(path);
data_t* path2_data = walk_path(path2);
if(path_data == NULL || path2_data == NULL) {
printf("Merge failed, couldn't get path data\n");
return NULL;
}
char** new_dir_info = (char**)malloc(sizeof(char*) * (path2_data->size + path_data->size) );
if(new_dir_info == NULL)
return NULL;
int loop = 0;
while(loop < path_data->size) {
new_dir_info[loop] = path_data->data[loop];
loop++;
}
loop = 0;
while(loop < path2_data->size) {
new_dir_info[loop + path_data->size] = path2_data->data[loop];
loop++;
}
free(path_data);
free(path2_data);
return new_dir_info;
}
合并路径函数返回的 char**
数组总是有损坏的数据,即字符数组中的字符被损坏而不是指针本身,尽管我希望它有字符串从目录条目传递给它的是随机字符串。
我单步执行了代码,发现数据在合并路径函数中被损坏,错误的来源仍然可能来自 walk_path()
。
最佳答案
这个
data_t* ret = (data_t*)malloc(sizeof(data_t*));
应该是
data_t* ret = (data_t*)malloc(sizeof(data_t));
通常在 C 中,void
指针不需要强制转换,因此可以删除代码中对 malloc
的所有强制转换,这使得上面的行看起来像:
data_t* ret = malloc(sizeof(data_t*));
为了排除像这样的错误,在对 malloc()
的调用中将类型加倍为 malloc
ate 是一个更好的步骤,但最好使用变量来与取消引用运算符一起分配给,如下所示:
data_t* ret = malloc(sizeof *ret);
还有这一行
data[loop_v] = entry->d_name;
复制指向条目名称的指针,而不是名称本身。
考虑使用
data[loop_v] = strdup(entry->d_name);
它为 entry->d_name
指向的副本动态分配空间。
或者代替
char**data;
定义
char (*data)[sizeof entry->d_name]; /* Array of pointers to char[as many char as entry->d_name is defined to have] */
或
char (*data)[sizeof ((struct dirent*)NULL)->d_name]; /* Array of pointers to char[as many char as entry->d_name is defined to have] */
并像这样分配给它(按照上面提出的模式):
data = malloc((size /* + 1 */) * sizeof *data); /* Not sure what the idea behind this +1 is. */
而不是
data[loop_v] = strdup(entry->d_name);
做
strcpy(data[loop_v], entry->d_name);
如果走这条路,您需要相应地调整 data_t.data
的定义。
关于c - malloc 内存中的数据损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57134728/