【发布时间】:2013-10-13 03:01:06
【问题描述】:
在 Zed 的流行(观点)系列中,在“堆和堆栈”一章中,数据库的代码如下
请注意这是 Zed Shaw 的代码
struct Address {
int id;
int set;
char name[MAX_DATA];
char email[MAX_DATA];
};
struct Database {
struct Address rows[MAX_ROWS];
};
struct Connection {
FILE *file;
struct Database *db;
};
struct Connection *Database_open(const char *filename, char mode)
{
struct Connection *conn = malloc(sizeof(struct Connection));
if(!conn) die("Memory error");
conn->db = malloc(sizeof(struct Database));
if(!conn->db) die("Memory error");
if(mode == 'c') {
conn->file = fopen(filename, "w");
} else {
conn->file = fopen(filename, "r+");
if(conn->file) {
Database_load(conn);
}
}
if(!conn->file) die("Failed to open the file");
return conn;
}
void Database_create(struct Connection *conn)
{
int i = 0;
for(i = 0; i < MAX_ROWS; i++) {
// make a prototype to initialize it
struct Address addr = {.id = i, .set = 0};
// then just assign it
conn->db->rows[i] = addr;
}
}
我觉得在他的 Database_create 函数中,他调用了 struct Address 形式的分配内存,而内存 f 已经分配给创建 struct database ,有点奇怪。
然后我通过这种思路推断出他两次调用 malloc 的事实,首先分配堆内存用于创建 Connection,然后再次分配用于在结构 Connection(即 Databse)中创建结构类型也很奇怪..我推断可能 Zed 知道并理解结构嵌套必须逐层构建。
就在此处发布问题之前,我决定编写一个简单的嵌套结构类型,并尝试通过一个 malloc 调用创建的最外层结构访问结构层内的数据....我的理由是,如果我认为没有必要逐层构造嵌套结构是真的,我可以访问嵌套数据而不会出现分段错误。我做到了
代码如下
#include<stdlib.h>
#include<stdio.h>
struct Killfly{
char str[20];
};
struct wtf
{
struct Killfly a;
};
struct wtf2{
struct wtf k;
};
int main(){
struct wtf2*fly=malloc(sizeof(struct wtf2));
printf("size of %ld \n",sizeof(*fly));
fly->k.a.str[0]='a';
//printf("size of wtf is %ld \n",sizeof(wtf));
free(fly);
return 0;
}
并且它在没有段错误的情况下写入
问题
那么为什么 Zed 放置多个 malloc 调用,以及为什么当他已经为结构数据库分配空间时,在函数 Database_struct 中,在 for 循环中,他继续调用基于堆栈的 struct Address 对象并将它们放入数组中上述类型?
【问题讨论】:
-
“那么为什么 Zed 会发出多个 malloc 调用” - 他在考验我对人性的信心
-
@EdHeal 通过那句话,你的意思是有一个明显的答案,我的思路是错误的?
-
因为他想要更多的堆栈内存(这就是
malloc的目的) -
Zed 不是在低俗小说中被杀的吗?
-
您有真正的问题需要帮助吗?