【发布时间】:2011-02-24 13:50:39
【问题描述】:
我知道这个问题一直存在,但我发现答案有点模糊、冗长或/和令人困惑;所以我将专门参考我的代码以充分理解这一点。
所以我得到了这个结构:
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;
}
还有一个主要功能:
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]);
}
发出 strncpy 以在“add_song()”中添加歌曲时出现分段错误。
我在做什么严重错误?正如多次听到的那样,c 中没有“正确”的实现方式,只要它有效并且没有错误,没关系,但作为初学者,获得一些关于使用内存分配的谨慎反馈或建议会很棒以及复杂的数据结构。
非常感谢! /s
【问题讨论】:
-
char song[] = "song 1\0";这会添加两个空终止字符。一旦你使用“”,编译器就会为你添加一个不可见的空终止,你不必手动做。 "x" 与 {'x', '\0'} 相同。
-
@Vlad 这是一个艰难的选择。要么用 C/C++ 编写,将程序员 90% 的时间用于内存管理,要么选择另一种语言,将 90% 的程序执行时间用于同一目的。 =)
-
@Lundin:不完全正确。我想说,如果您需要在关键路径上分配/释放内存 - 这是一个糟糕的设计,无论您使用 C 还是 C++ 都是一个问题,否则使用 C++ 中的
std::string不会损害您的性能,特别是如果你有一个对象池(甚至是无锁对象池)。