c - 如何为 C 中的结构正确分配内存?
问题描述
我不知道如何在我的 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 停止一次而不是两次,因此迭代列表更快。
推荐阅读
- python - Pydantic 是否接受具有单值和多值的相同查询?
- html - 我怎样才能在引导工作室中制作这种类型的布局
- python - 如何修复替换中的 ValueError
- heroku - 构建成功后超出 Heroku 内存配额
- python - 从 CSV 列中去除空格并覆盖列
- python - 在运行时提取 python 轮子的版本
- r - 使用 eventReactive 和 inputMatrix 需要按两次按钮
- reactjs - React 记忆化是如何在幕后工作的?
- powershell - 将多个自定义许可证分配给 o365 用户
- javascript - Firefox 85 中使用顶级等待的条件导入