作为一个练习,我目前正在做一个项目:一个基于个人文本的数据库(因此是一个(个人和非(数据的集合,排列在一个文件中,作为一种"数据库"(用C语言进行管理。
我想把所有的管理功能都放在一个.h
文件中,把主要功能(与用户交互的功能,数据库的所有者(放在.c
文件中。.h
文件还没有完成,但我正在慢慢测试每个函数,看看它们是否正常工作。
特别是这一次,我很害怕,因为我找不到堆满的原因(如果它真的满了…(
以下是完整的代码:(感兴趣的函数被称为"initobj"。尽管我分享了完整的代码,认为理解它可能很有用(
#include <time.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#if defined(_WIN32)
#define PATH "C:\Database\"
#elif defined(_WIN64)
#define PATH "C:\Database\"
#elif defined(__linux__)
#define PATH "/Database/"
#else
#define PATH NULL
#endif
struct user{
unsigned int uid;
char *username;
char *password;
};
struct file{
unsigned int uid;
char *filename;
char *content;
};
char *initpath(void){
char filename[] = "Database.txt";
char *path = (char *)malloc(sizeof(char) * strlen(PATH) + 1);
if(path != NULL){
strcpy(path, PATH);
mkdir(path);
strcat(path, filename);
return path;
}
else
return NULL;
}
int initobj(struct user *elem, unsigned uid, char *username, char *password){
elem->uid = uid;
if((elem->username = (char *)malloc(sizeof(char) * strlen(username) + 1)) != NULL)
strcpy(elem->username, username);
else
return -1;
if((elem->password = (char *)malloc(sizeof(char) * strlen(password) + 1)) != NULL)
strcpy(elem->password, password); //Password is copied into the structure as a normal string. Future updata: encrypting the password
else
return -1;
return 0;
}
int insobj(int database, struct user elem){}
int checkid(int database, unsigned int id){}
int checkusr(int database, char *username){}
int checkpasw(int database, char *password){}
这里是主要的功能代码:
#include <time.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "database.h"
struct user playground;
int main(int argc, char *argv[]){
srand(time(0));
int err;
struct user *p = &playground;
char *filepath = initpath();
if(filepath != NULL && argc == 3){
if((err = initobj(p, (rand() % 999), argv[1], argv[2])) == 0)
printf("%u, %s, %s <- Data inserted.n", p->uid, p->username, p->password);
else
printf("[DEBUG]: From function 'initobj' : %d.n", err);
}
else
fprintf(stderr, "%s: Not enought arguments.n", argv[0]);
}
程序不断返回我-1:
C:UsersComputerDesktopACCESSDatabaselib>dat username password
[DEBUG]: From function 'initobj' : -1.
因此意味着malloc无法在头中分配空间。我就是不明白为什么。
至少这些问题:
代码无法分配足够的空间@Johnny Mopp
char filename[] = "Database.txt";
char *path = (char *)malloc(sizeof(char) * strlen(PATH) + 1); // Wrong size & sense
if(path != NULL){
strcpy(path, PATH);
mkdir(path);
strcat(path, filename); // !! Undefined behavior (UB) !!
return path;
}
有了strcat(path, filename);
的UB,剩下的代码就无关紧要了。
取而代之的是
同时考虑
PATH
和filename
不需要铸造。
按
sizeof(char) * strlen(PATH) + 1
缩放应为sizeof(char) * (strlen(PATH) + 1)
。CCD_ 9是1并且也不需要。char filename[] = "Database.txt"; // PATH filename minus its char *path = malloc(strlen(PATH) + (sizeof filename - 1) + 1);
mkdir()
可能会失败
更好的代码将测试mkdir()
的成功。
if (mkdir(path)) {
Handle_failure();
}