Чтобы уменьшить «много частей памяти, разбросанных повсюду» (и хлопот отслеживания того, где все маленькие части выделены / освобождены), вы можете выделить один кусок памяти для нескольких вещей (например, структура плюс строка). Например:
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;
}
В этом случае; Процессор останавливается, ожидая получения node
из памяти, затем останавливается, ожидая, пока node->team
будет выбран из памяти. Теперь представьте это:
while(team != NULL) {
printf("name: %s\n", team->name)
team = team->next;
}
В этом случае; Процессор останавливается один раз, а не два, поэтому итерация по списку происходит быстрее.