我不知道如何为我的C程序中的结构分配内存而不会出现分段错误。
typedef struct Player{
char *name, *surname;
int xp;
} Player;
typedef struct Team{
char *name;
Player *player;
} Team;
typedef struct List
{
Team *team;
struct List *next;
} List_Node;
我需要列出一系列具有一系列玩家的团队,但是对于我的程序而不是Segfault我需要malloc每个结构的每个成员。然后我必须释放每个结构的每个成员。这是一个合理的大项目,我得到堆损坏错误,我不知道我是否正确初始化我的结构。
将指针初始化为main。
List_Node *list_node = (List_Node*)malloc(sizeof(List_node));
而且功能
void create_list_Node(List_Node *temp)
{
temp->team = malloc....
temp->team->name = malloc....
temp->team->player = malloc....
temp->team->player->name = malloc....
temp->team->player->surname = malloc....
temp->next = NULL;
}
以节点作为参数调用。
为了减少“遍布各处的许多内存”(以及跟踪所有小块被分配/释放的位置的麻烦),您可以为多个事物分配单个内存(例如,结构加上字符串) 。例如:
typedef struct Player{
char *name, *surname;
int xp;
} Player;
typedef struct Team{
struct Team *next;
char *name;
Player *player;
} Team;
Player *createPlayer(char *name, char *surname, int xp) {
Player *newPlayer;
int len1, len2;
len1 = strlen(name);
len2 = strlen(surname);
newPlayer = malloc(sizeof(Player) + len1+1 + len2+1);
if(newPlayer != NULL) {
newPlayer->next = NULL;
newPlayer->name = (char *)newPlayer + sizeof(Player);
memcpy(newPlayer->name, name, len1+1);
newPlayer->surname = newPlayer->name + len1+1;
memcpy(newPlayer->surname, surname, len2+1);
plyer->xp = xp;
}
return newPlayer;
}
Team *createTeam(Player *player, char *name) {
Team *newTeam;
int len1;
len1 = strlen(name);
newTeam = malloc(sizeof(Team) + len1+1);
if(newTeam != NULL) {
newTeam->next = NULL;
newTeam->name = (char *)newTeam + sizeof(Team);
memcpy(newTeam->name, name, len1+1);
newTeam->player = player;
}
return newTeam;
}
这也意味着很容易释放任何东西 - 例如你可以free(player)
而不会搞乱个别领域。
注意:我摆脱了List_Node
并在next
结构中放置了一个Team
字段。这有助于提高迭代的性能(并且还可以减少过多的malloc / free)。要理解这一点,假设您列出了所有团队名称并执行以下操作:
while(node != NULL) {
printf("name: %s\n", node->team->name)
node = node->next;
}
在这种情况下; CPU在等待node
从内存中取出时停止,然后在等待node->team
从内存中取出时停止。现在想象一下:
while(team != NULL) {
printf("name: %s\n", team->name)
team = team->next;
}
在这种情况下; CPU会停止一次而不是两次,因此迭代列表会更快。
如果我们使用此函数来创建一个空节点:
void create_list_Node(List_Node *temp)
{
temp->team = calloc(1, sizeof(Team));
temp->team->player = calloc(1, sizeof(Player));
temp->next = NULL;
}
如何分配namn:s和surname取决于这些字符串的来源。如果你得到一个没有其他代码可以释放的分配指针,你可以“采用”指针:
char *mystring;
... code that allocates
temp->team->name = mystring;
如果你有一个本地字符串数组,只需复制它:
char local[100];
... code that fill it, maybe gets()
temp->team->name = strdup(local);
不要忘记释放字符串和结构!