ヒープとスタックの構造体の違いを理解しようとしています。Book、Author、Shelfの構造体は次のとおりです。本には複数の著者がいて、棚には複数の本があります。
struct Author {
char name[NAME_LENGTH];
};
struct Book {
char title[TITLE_LENGTH];
struct Author authors[AUTHORS_PER_BOOK];
int author_count;
};
struct Shelf {
struct Book books[BOOKS_PER_SHELF];
int book_count;
};
名前とタイトルを指定して、Author構造体とBook構造体を作成する機能がたくさんあります。そして、本に著者を追加するための機能。Cは厳密に値で渡されることを理解しているので、add_authors_to_book関数で本へのポインターを使用しました。これらの関数はローカルで作成され、スタック(?)上にあると想定しています。
struct Author new_author(char name[]) {
struct Author author;
strcpy(author.name, name);
return author;
}
struct Book new_book(char title[]) {
struct Book book;
strcpy(book.title, title);
book.author_count = 0;
return book;
}
void print_book(struct Book book) {
printf("%s\nby", book.title);
int i, n;
for (i = 0, n = book.author_count; i < n; i++) {
printf(" %s,", book.authors[i].name);
}
printf("\b.\n");
}
void add_author_to_book(struct Book *book, struct Author author) {
book->authors[book->author_count] = author;
book->author_count++;
}
棚を山に置いてほしい。私はそれのためにメモリを割り当てて、それを以下で解放しています。
struct Shelf *new_shelf() {
struct Shelf *shelf = malloc(sizeof(struct Shelf));
shelf->book_count = 0;
return shelf;
}
void delete_shelf(struct Shelf *shelf) {
free(shelf);
}
void print_shelf(struct Shelf *shelf) {
printf("Shelf has the %d book(s),\n", shelf->book_count);
int i, n;
for (i = 0, n = shelf->book_count; i < n; i++) {
print_book(shelf->books[i]);
}
}
私の質問は、本を棚に追加することに関するものです。以下では、最後のインデックスで本の構造体を棚の本に割り当てています。この構造体ブックは、ヒープまたはスタックのどこにありますか?Cは、add_book_to_shelfに渡すときに、作成者を含むBook構造全体のクローンを自動的に作成しますか?値渡しは、そのようなネストされた構造体で機能しますか?
また、本とその著者が使用していたメモリをどのように解放しますか?
void add_book_to_shelf(struct Shelf *shelf, struct Book book) {
shelf->books[shelf->book_count] = book;
shelf->book_count++;
}
これが私のテストコードです、
int main(int argc, char *argv[]) {
struct Shelf *shelf = new_shelf();
struct Book book = new_book("Freakonomics");
add_author_to_book(&book, new_author("Stephen Dubner"));
add_author_to_book(&book, new_author("Steven Levitt"));
add_book_to_shelf(shelf, book);
print_shelf(shelf);
delete_shelf(shelf);
return 0;
}