[英]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
。
几乎尝试了所有方法,但问题仍然存在。 寻求您的帮助。
你有两个问题:
和
malloc(150*sizeof(dbEntry*))
您将 memory 分配给 150个指向dbEntry
结构的指针,而不是dbEntry
结构本身。
我建议您从变量本身获取要分配的数据大小,如下所示:
dbEntry *entries = malloc(150 * sizeof *entries);
在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.