簡體   English   中英

分配內存中的數據損壞

[英]Data corruption in malloc'ed memory

每當我嘗試訪問使用malloc獲取的malloc中的數據時,數據就會損壞

我正在編寫一個程序,該程序讀取Linux目錄並在“字符串數組”(c中的char **數組)中寫入文件和子目錄的名稱。 它使用dirent.h功能(如readdir() readdir返回一個Dirent結構,該結構具有dname[256] ,即目標目錄中文件/子目錄的名稱。 我將Dirent字符串(char *)等同於char **數組中已分配位置的索引

我基本上有一個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()但最好使用可變分配與對其操作,這樣一起:

   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的定義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM