malloc'中的数据损坏;记忆

malloc'中的数据损坏;记忆,c,arrays,string,directory,malloc,C,Arrays,String,Directory,Malloc,当我试图访问使用malloc获取的内存中的数据时,数据已损坏 我正在编写一个程序,它读取Linux目录,并将文件和子目录的名称写入“字符串数组”(c中的char**array)。它使用dirent.h功能操作,如readdir()。readdir返回一个dirent结构,该结构的dname[256]是目标目录中文件/子目录的名称。我将dirent字符串(char*)等同于char**数组中malloced位置的索引 我基本上有一个walk_path()函数,它读取目录条目并将其名称写入mallo

当我试图访问使用
malloc
获取的内存中的数据时,数据已损坏

我正在编写一个程序,它读取Linux目录,并将文件和子目录的名称写入“字符串数组”(c中的char**array)。它使用
dirent.h
功能操作,如
readdir()
。readdir返回一个dirent结构,该结构的
dname[256]
是目标目录中文件/子目录的名称。我将dirent字符串(char*)等同于char**数组中malloced位置的索引

我基本上有一个
walk_path()
函数,它读取目录条目并将其名称写入malloced位置,然后返回该位置

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;
}
data\t*walk\u路径(char*path){
int size=0;
if(路径==NULL){
printf(“空路径\n”);
返回NULL;
}
结构方向*条目;
DIR*DIR\u l=opendir(路径);
if(dir_l==NULL){
char**data=(char**)malloc(sizeof(char*)*2);
数据[0]=路径;
data_t*ret=(data_t*)malloc(sizeof(data_t));
ret->data=数据;
ret->size=1;
返回ret;
}
while((entry=readdir(dir_l))!=NULL){
如果(!strcmp(条目->数据单元名称,“.”)| |!strcmp(条目->数据单元名称,“…”))
继续;
大小++;
}
closedir(dir_l);
字符**数据=(字符**)malloc(sizeof(字符*)*size+1);
int-loop_v=0;
dir_l=opendir(路径);
while((entry=readdir(dir_l))!=NULL&&loop_v数据单元名称,“.”)| |!strcmp(条目->数据单元名称,“…”))
继续;
数据[loop_v]=条目->数据单元名称;
loop_v++;
}
closedir(dir_l);
data_t*ret=(data_t*)malloc(sizeof(data_t*));
ret->size=(size\t)size;
ret->data=数据;
返回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**merge_路径(char*path,char*path2){
数据路径数据=行走路径(路径);
数据路径2数据=行走路径(路径2);
if(路径_数据==NULL | |路径2 _数据==NULL){
printf(“合并失败,无法获取路径数据\n”);
返回NULL;
}
char**new_dir_info=(char**)malloc(sizeof(char*)*(path2_数据->大小+路径数据->大小));
如果(新目录信息==NULL)
返回NULL;
int循环=0;
while(循环size){
新建目录信息[循环]=路径数据->数据[循环];
loop++;
}
循环=0;
while(循环大小){
新建目录信息[循环+路径数据->大小]=path2\u数据->数据[循环];
loop++;
}
自由(路径_数据);
免费(路径2_数据);
返回新的目录信息;
}
merge path函数返回的
char**
数组始终具有损坏的数据,即字符数组中的字符已损坏,而不是指针本身,尽管我希望它具有从目录项传递给它的字符串,但它具有随机字符串

我仔细检查了代码,发现数据在合并路径函数中被损坏,错误的来源仍然可能来自
walk\u 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;
   data[loop_v] = strdup(entry->d_name);
定义

   char (*data)[sizeof entry->d_name]; /* Array of pointers to char[as many char as entry->d_name is defined to have] */

并按如下方式分配给它(遵循上述模式):

而不是

   char**data;
   data[loop_v] = strdup(entry->d_name);


如果选择此路线,您需要相应地调整
数据的定义。

sizeof(char*)*size+1
是否正确?您想分配指向char和一个字节的指针的计数吗?是的,我打算将这个额外的字节用于不同的数据,或者只是作为数组末尾的空标识符。
   strcpy(data[loop_v], entry->d_name);