为结构内的字符串分配内存

Smo*_*kie 6 c malloc struct

我知道这个问题已经存在,但我发现答案有点模糊,长时间或/和令人困惑; 所以我将专门提到我的代码,以充分说明问题.

所以我得到了这个结构:

typedef struct album {
  unsigned int year;
  char *artist;
  char *title;
  char **songs;
  int songs_c;
} album ;
Run Code Online (Sandbox Code Playgroud)

以下功能:

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;
}
Run Code Online (Sandbox Code Playgroud)

主要功能:

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]);
}
Run Code Online (Sandbox Code Playgroud)

发出strncpy以在"add_song()"中添加歌曲时出现分段错误.

我做错了什么?听到很多次,在c中没有"正确"的实现方式,只要它有效并且它没有错误,没关系,但是作为一个初学者会很高兴得到一些关于使用内存分配的警告反馈或建议以及复杂的数据结构.

谢谢你!/秒

Bor*_*lid 3

if (index == 0) {
    a->songs = malloc( strlen(song) );
} else a->songs[index] = malloc( strlen(song)+1 );
Run Code Online (Sandbox Code Playgroud)

这不是一个好主意。您必须x通过 via进行歌曲a->songs[x],因此您需要分配a->songsas (char**)malloc(sizeof(char*)*numsongs)。当只有一首歌曲时,仍然应该将其放入子指针中。

你出现段错误的一个原因是因为上面没有+1像其他地方一样的 NUL ......另一个原因是你没有将 添加+1到长度中strncpy,所以实际上没有任何内容被终止。