在《笨办法学C语言》中,习题17-内存分配:堆和栈
代码报错
#include
#include
#include
#include
#include
#define MAX_DATA 512
#define MAX_ROWS 100
struct Address{
int id;
int set;
char name[MAX_DATA];
char email[MAX_ROWS];
};
struct Database{
struct Address rows[MAX_ROWS];
};
struct Connection{
FILE *file;
struct Database *db;
};
void die(const char *message)
{
if(errno){
perror(message);
}else{
printf("ERROR: %s\n",message);
}
exit(1);
}
void Address_print(struct Address *addr)
{
printf("%d %s %s\n",addr->id, addr->name, addr->email);
}
void Database_load(struct Connection *conn)
{
int rc = fread(conn->db,sizeof(struct Database),1,conn->file);
if(rc != 1)
die ("Failed to load database.");
}
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_close(struct Connection *conn)
{
if(conn){
if(conn->file)
fclose(conn->file);
if(conn->db)
free(conn->db);
free(conn);
}
}
void Database_write(struct Connection *conn)
{
rewind(conn->file);
int rc = fwrite(conn->db,sizeof(struct Database),1,conn->file);
if(rc == 1)
die("Failed to write database.");
rc = fflush(conn->file);
if(rc == -1)
die("Cannot flush database.");
}
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;
}
}
void Database_set(struct Connection *conn,int id,const char *name,const char *email)
{
struct Address *addr = &conn->db->rows[id];
if (addr->set)
die ("Already set,delete it frist");
addr->set = 1;
//WARNING: bug ,read the "How To Break It" and fix this
char *res = strncpy(addr->name,name,MAX_DATA);
//demostrate the strncpy bug
if(!res)
die("Name copy failed");
res = strncpy(addr->email,email,MAX_DATA);
if(!res)
die("Email copy failed");
}
void Database_get(struct Connection *conn,int id)
{
struct Adress *addr = &conn->db->rows[id];
if(addr->set){
Address_print(addr);
}else{
die("ID is not set");
}
}
void Database_delete(struct Connection *conn,int id)
{
struct Address addr = {.id = id,.set = 0};
conn->db->rows[id] = addr;
}
void Database_list(struct Connection*conn)
{
int i = 0;
struct Database *db = conn->db;
for(i = 0;i < MAX_ROWS; i++){
struct Address *cur = &db->rows{i};
if(cur->set){
Address_print(cur);
}
}
}
int main(int argc,char argv[])
{
if(argc < 3)
die("USAGE:ex17 [action params]" );
char *filename = argv[1];
char action = argv[2][0];
struct Connection *conn = Database_open(filename,action);
int id = 0;
if (argc > 3)id = atoi(argv[3]);
if (id >= MAX_ROWS) die("There's not that many records.");
switch(action){
case 'c':
Database_create(conn);
Database_write(conn);
break;
case 'g':
if(argc != 4)
die("Need an id to get");
Database_get(conn,id);
break;
case 's':
if(argc != 6)
die("Need id,name,email to set");
Database_set(conn,id,argv[4],argv[5]);
Database_write(conn);
break;
case 'd':
if(argc != 4)
die("Need id to delete");
Database_delete(conn,id);
Database_write(conn);
break;
case '1':
Database_list(conn);
break;
default:
die("Invalid action: c=create, g=get, s=set, d=del,l=list");
}
Database_close(conn);
return 0;
}
E:/学习/C语言/笨办法学C/ex17.c 0 -1 In function 'Database_get':
E:/学习/C语言/笨办法学C/ex17.c 131 24 [警告] initialization of 'struct Adress *' from incompatible pointer type 'struct Address *' [-Wincompatible-pointer-types]
E:/学习/C语言/笨办法学C/ex17.c 133 9 [错误] invalid use of undefined type 'struct Adress'
E:/学习/C语言/笨办法学C/ex17.c 134 17 [警告] passing argument 1 of 'Address_print' from incompatible pointer type [-Wincompatible-pointer-types]
E:/学习/C语言/笨办法学C/ex17.c 37 36 [说明] expected 'struct Address *' but argument is of type 'struct Adress *'
E:/学习/C语言/笨办法学C/ex17.c 0 -1 In function 'Database_list':
E:/学习/C语言/笨办法学C/ex17.c 152 25 [警告] initialization of 'struct Address ' from incompatible pointer type 'struct Address ()[100]' [-Wincompatible-pointer-types]
E:/学习/C语言/笨办法学C/ex17.c 152 34 [错误] expected ',' or ';' before '{' token
E:/学习/C语言/笨办法学C/ex17.c 0 -1 At top level:
E:/学习/C语言/笨办法学C/ex17.c 161 5 [警告] second argument of 'main' should be 'char **' [-Wmain]
E:/学习/C语言/笨办法学C/ex17.c 0 -1 In function 'main':
E:/学习/C语言/笨办法学C/ex17.c 165 19 [警告] initialization of 'char *' from 'char' makes pointer from integer without a cast [-Wint-conversion]
E:/学习/C语言/笨办法学C/ex17.c 166 23 [错误] subscripted value is neither array nor pointer nor vector
E:/学习/C语言/笨办法学C/ex17.c 3 0 In file included from E:/学习/C语言/笨办法学C/ex17.c
E:/学习/C语言/笨办法学C/ex17.c 170 29 [警告] passing argument 1 of 'atoi' makes pointer from integer without a cast [-Wint-conversion]
C:/Program Files/RedPanda-Cpp/MinGW64/x86_64-w64-mingw32/include/stdlib.h 434 32 [说明] expected 'const char *' but argument is of type 'char'
E:/学习/C语言/笨办法学C/ex17.c 190 28 [警告] passing argument 3 of 'Database_set' makes pointer from integer without a cast [-Wint-conversion]
E:/学习/C语言/笨办法学C/ex17.c 111 62 [说明] expected 'const char *' but argument is of type 'char'
E:/学习/C语言/笨办法学C/ex17.c 190 36 [警告] passing argument 4 of 'Database_set' makes pointer from integer without a cast [-Wint-conversion]
E:/学习/C语言/笨办法学C/ex17.c 111 79 [说明] expected 'const char *' but argument is of type 'char'
让程序正确的运行