2

ヒープとスタックの構造体の違いを理解しようとしています。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;
}
4

3 に答える 3

2

答えは、本が棚自体にあるということです。本を直接格納するようにシェルフ構造体を宣言したため、その中に本を格納するために必要なフルスペースが含まれています。したがって、本を棚に割り当てると、実際にはその値が棚にコピーされます。したがって、棚がスタックにある場合、本はスタックにあり、その逆も同様です。

于 2012-09-13T03:45:14.967 に答える
1

本をadd_book_to_shelfにコピーしています。これは、本がヒープ上にあることを意味します。

mainで作成した本はスタックにありますが(自動変数であるため)、add_book_to_shelfでは、本はヒープ上の棚の一部として割り当てられている本の配列にコピーされます。

于 2012-09-13T03:44:45.390 に答える
1

free()の使用に関しては、テストコードにはfree(shelf)だけで十分です。シェルフは、データがヒープに動的に割り当てられたポインターであるため、free()を使用して削除する必要があります。書籍の配列を動的に割り当てなかったため、free(shelf-> books [i])を使用する必要はありません。配列内のBOOKS_PER_SHELF要素を自動的に宣言します。これはメモリ管理には効率的ではないかもしれませんが、割り当て解除は非常に簡単で読みやすくなります。

于 2012-09-13T05:39:41.350 に答える