簡體   English   中英

為什么 malloc/calloc 無法將 memory 分配給結構數組中的某些成員?

[英]Why does malloc/calloc fail to allocate memory to certain members in an array of structures?

我想要一些 function ( save() ) 來獲取指向結構數組dbEntry的指針並用數據填充它。 這就是 memory 管理問題出現的地方。

這是我的代碼:

結構本身:

typedef struct dbEntry {
          unsigned int id;
          char* type;
          char* name;
          unsigned int parent_id;
          unsigned char* md5;
} dbEntry;

Memory 分配和調用save()

int main(int argc, char const* argv[]){
          if (argc != 5) arg_error();

          if (strcmp(argv[1], "-s") == 0){
              FILE* database = fopen(argv[2], "wb");
              if (database == NULL) file_error();
              dbEntry* entries = malloc(150*sizeof(dbEntry*));
              for (int i=0; i<150; i++){
                  entries[i].id = 0;
                  entries[i].parent_id = 0;
                  entries[i].name = malloc(50*sizeof(char));
                  entries[i].type = malloc(10*sizeof(char));
                  entries[i].md5 = malloc(MD5_DIGEST_LENGTH*sizeof(unsigned char));
              }
              int entry_num = save(argv[4], 0, &entries);

save()

int save(char* dir_path, unsigned int parent, dbEntry** entries) {
          size_t path_len = strlen(dir_path);
          if (dir_path[path_len - 1] != '/') strcat(dir_path, "/");
          char dp_copy[path_len];
          strcpy(dp_copy, dir_path);
          DIR* dir = opendir(dir_path);
          struct dirent* dirent = readdir(dir);
          dirent = readdir(dir);
          dirent = readdir(dir);
          unsigned int id = 0;
          char* fpath;

          if (dirent == NULL) {
                  fprintf(stderr,
                          "Directory %s doesn't exist or can't be "
                          "opened. Check permissions\n",
                          dir_path);
                  exit(-1);
          }

          while (dirent != NULL) {
                  entries[id]->id = id;
                  strcpy(entries[id]->name, dirent->d_name);
                  entries[id]->parent_id = parent;

                  if (dirent->d_type == 8) {
                          strcpy(entries[id]->type, "file");
                          size_t len = strlen(dir_path)+strlen(dirent->d_name);
                          fpath = malloc(len);
                          strcpy(fpath, dir_path);
                          strcat(fpath, dirent->d_name);
                          FILE* file = fopen(fpath, "rb");
                          if (file == NULL){
                                  printf("Could not open file %s for reading\n", fpath);
                                  exit(-1);
                          }
                          md5digest(file, entries[id]->md5);
                          fclose(file);
                          printf("Saved %s\n", strcat(dir_path, dirent->d_name));

GDB output:

57              while (dirent != NULL) {
(gdb) n
58                      entries[id]->id = id;
(gdb) n
59                      strcpy(entries[id]->name, dirent->d_name);
(gdb) n
60                      entries[id]->parent_id = parent;
(gdb) n
62                      if (dirent->d_type == 8) {
(gdb) n
63                              strcpy(entries[id]->type, "file");
(gdb) n
64                              size_t len = strlen(dir_path)+strlen(dirent->d_name);
(gdb) n
65                              fpath = malloc(len);
(gdb) n
66                              strcpy(fpath, dir_path);
(gdb) n
67                              strcat(fpath, dirent->d_name);
(gdb) p entries
$1 = (dbEntry **) 0x7ffffffee110
(gdb) p entries[0]
$2 = (dbEntry *) 0x8403490
(gdb) p entries[1]
$3 = (dbEntry *) 0x0
(gdb) p entries[2]
$4 = (dbEntry *) 0x8403260
(gdb) p entries[3]
$5 = (dbEntry *) 0xf625f4cc70b40b00
(gdb) p entries[4]
$6 = (dbEntry *) 0x7ffffffee220
(gdb) p entries[5]
$7 = (dbEntry *) 0x0
(gdb) p entries[6]
$8 = (dbEntry *) 0x8001890 <__libc_csu_init>
(gdb) p entries[7]
$9 = (dbEntry *) 0x7ffffeb51b97 <__libc_start_main+231>
(gdb) p entries[8]
$10 = (dbEntry *) 0x2000000000
(gdb) p entries[0]->name
$11 = 0x8403950 ".bash_history"
(gdb)

由於某種原因,它未能為entries[1]entries[5]等分配 memory ,因此程序在嘗試引用entries[1]時返回Address boundary error

幾乎嘗試了所有方法,但問題仍然存在。 尋求您的幫助。

你有兩個問題:

  1. malloc(150*sizeof(dbEntry*))

    您將 memory 分配給 150個指向dbEntry結構的指針,而不是dbEntry結構本身。

    我建議您從變量本身獲取要分配的數據大小,如下所示:

     dbEntry *entries = malloc(150 * sizeof *entries);
  2. save function 中,變量entries本質上是一個指向dbEntry結構數組的指針。 您將其視為指向結構的指針數組(指向數組的指針與指針數組不同)。 您需要取消引用指針以獲取原始指針,然后可以像結構數組一樣取消引用:

     (*entries)[id].id = id;

    或者干脆不將它作為指向指針的指針傳遞:

     // Note only one asterisk // v int save(char* dir_path, unsigned int parent, dbEntry* entries) {... entries[id].id = id; // Entries can be treated like a normal array of structures... }

暫無
暫無

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

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