この質問はあちこちにありましたが、私は少し霧がかかり、長いか、混乱しています。だから私は完全にポイントを得るために私のコードを具体的に参照するつもりです。構造体内の文字列にメモリを割り当てる
typedef struct album {
unsigned int year;
char *artist;
char *title;
char **songs;
int songs_c;
} album ;
次のような機能:
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;
}
そして主な機能:に曲を追加するためにはstrncpyを発行
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]);
}
セグメンテーションフォールト
はので、私は、この構造体を得ました"add_song()"私は批判的に何をしていますか?何度も聞いたように、動作していてバグでない限り、Cの実装方法は「正しい」ものではありません。大丈夫ですが、初心者であれば、メモリの割り当てに関する注意やフィードバック複雑なデータ構造とともに
ありがとうございました!あなたは、バッファのみを文字列自体のためのスペースがあり、それを伝えるため、
a->artist = malloc(strlen(artist) + 1);
strncpy(a->artist, artist, strlen(artist)); // null terminator is not placed
: /sの
char song [] = "song 1 \ 0";これにより、2つのヌル終了文字が追加されます。 ""を使用するとすぐに、コンパイラは目に見えないヌル終了を追加しますが、手動で行う必要はありません。 "x"は{'x'、 '\ 0'}と同じです。 – Lundin
@Vladそれは厳しい選択です。 C/C++で記述し、メモリ管理のためにプログラマーの時間の90%を費やすか、別の言語を選び、同じ目的のためにプログラム実行時間の90%を費やす。 =) – Lundin
@ Lundin:正確ではない。あなたがクリティカルパスにメモリを確保/解放する必要がある場合、それは悪い設計であり、CやC++を使用しているかどうかにかかわらず問題です。そうでなければC++の 'std :: string'を使用しません特にオブジェクトプール(またはロックフリーのオブジェクトプール)を使用している場合は、パフォーマンスを低下させる可能性があります。 –