Wiem, że to pytanie było już w pobliżu, ale znalazłem odpowiedzi trochę mgliste, długie lub/i mylące; więc zamierzam konkretnie odnieść się do mojego kodu, aby w pełni zrozumieć punkt.Przydzielanie pamięci na ciąg wewnątrz struktury
więc mam tej struktury:
typedef struct album {
unsigned int year;
char *artist;
char *title;
char **songs;
int songs_c;
} album ;
następujące funkcje:
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;
}
i główną funkcję:
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]);
}
winy segmentacji przy wydawaniu strncpy aby dodać piosenkę w "add_song()".
Co robię krytycznie źle? jak słyszałem kilka razy, nie ma "poprawnej" metody implementacji wc, o ile działa i nie ma błędów, jest OK, ale jako początkujący świetnie byłoby uzyskać ostrzeżenie zwrotne lub porady dotyczące korzystania z alokacji pamięci wraz ze złożonymi strukturami danych.
Wielkie dzięki! /s
char song [] = "song 1 \ 0"; Spowoduje to dodanie dwóch znaków kończących. Jak tylko użyjesz "", kompilator doda dla ciebie niewidoczne zakończenie zerowe, nie musisz tego robić ręcznie. "x" jest takie samo jak {'x', '\ 0'}. – Lundin
@Vlad To trudny wybór. Napisz do C/C++ i poświęć 90% czasu programisty na zarządzanie pamięcią lub wybierz inny język i wydaj 90% czasu wykonania programu w tym samym celu. =) – Lundin
@Lundin: Nie do końca prawda. Powiedziałbym, że jeśli musisz przydzielić/zwolnić pamięć na krytycznej ścieżce - jest to zły projekt i jest problemem bez względu na to, co używasz C lub C++, w przeciwnym razie użycie 'std :: string' z C++ nie będzie zaszkodzić wydajności, szczególnie jeśli masz pulę obiektów (lub nawet pulę obiektów bez blokady). –