Sé que esta pregunta ha existido, pero las respuestas me parecieron un poco confusas, largas y/y confusas; así que voy a referirme específicamente a mi código para obtener el punto por completo.Asignación de memoria para una cadena dentro de una estructura
Así que me dio esta estructura:
typedef struct album {
unsigned int year;
char *artist;
char *title;
char **songs;
int songs_c;
} album ;
las siguientes funciones:
struct album* init_album(char *artist, char *album, unsigned int year){
struct album *a;
a= malloc(sizeof(struct album));
a->artist = malloc(strlen(artist) + 1);
strncpy(a->artist, artist, strlen(artist));
a->title = malloc(strlen(album) + 1);
strncpy(a->title, album, strlen(album));
a->year = year;
return a;
}
void add_song(struct album *a, char *song){
int index = a->songs_c;
if (index == 0){
a->songs = malloc(strlen(song));
} else a->songs[index] = malloc(strlen(song)+1);
strncpy(a->songs[index], song, strlen(song));
a->songs_c= a->songs_c+1;
}
y una función principal:
int main(void){
char *name;
char artist[20] = "The doors";
char album[20] = "People are strange";
int year = 1979;
struct album *a;
struct album **albums;
albums = malloc(sizeof(struct album));
albums[0] = init_album((char *)"hihi", (char *)"hoho", 1988);
albums[1] = init_album((char *)"hihi1", (char *)"hoho1", 1911);
printf("%s, %s, %d\n", albums[0]->artist, albums[0]->title, albums[0]->year);
printf("%s, %s, %d\n", albums[1]->artist, albums[1]->title, albums[1]->year);
char song[] = "song 1\0";
add_song(albums[1], song);
free(albums[0]);
free(albums[1]);
}
Fallo de segmentación al emitir strncpy añadir una canción "add_song()".
¿Qué estoy haciendo muy mal? como se ha escuchado un montón de veces, no hay una forma "correcta" de implementación en c, siempre y cuando funcione y no tenga errores, está bien, pero como principiante sería genial recibir comentarios o consejos sobre el uso de la asignación de memoria junto con estructuras de datos complejas.
¡Muchas gracias! /s
canción de char [] = "canción 1 \ 0"; Esto agrega dos caracteres de terminación nula. Tan pronto como use "", el compilador agregará una terminación nula invisible para usted, no tiene que hacerlo manualmente. "x" es lo mismo que {'x', '\ 0'}. – Lundin
@Vlad Es una decisión difícil. Escriba en C/C++ y dedique el 90% del tiempo del programador para la gestión de la memoria, o elija otro idioma y dedique el 90% del tiempo de ejecución del programa para el mismo fin. =) – Lundin
@Lundin: No es exactamente cierto. Diría que si necesita asignar/liberar memoria en una ruta crítica, es un mal diseño, y es un problema sin importar qué use C o C++, de lo contrario, usar 'std :: string' de C++ no lo hará dañará su rendimiento, especialmente si tiene un grupo de objetos (o incluso grupo de objetos sin bloqueo). –