Es ist unklar, ob Sie das jemals gelöst haben, vielleicht hilft ein kurzes Beispiel. Unabhängig davon, ob Sie Speicher für X Anzahl der Bücher in array
am Anfang erstellen oder array
als ein Array von X-Zeiger auf Bücher erstellen, müssen Sie sicherstellen, dass Sie nicht mehr Bücher hinzufügen, als Sie speichern können. Die offensichtliche Möglichkeit, dies zu umgehen, ist das Hinzufügen einer zusätzlichen Variablen zu Ihrer stack
-Struktur, die den Speicher (oder die Anzahl der verfügbaren Zeiger) in array
und dann realloc
array
nach Bedarf verfolgt. Um den Raum in array
verfügbar zu verfolgen, könnten Sie einfach einen weiteren Zähler hinzufügen, sagen wir max_books
, z.B.
enum { NBOOKS = 10 };
typedef struct {
char *title;
int pages;
} book;
typedef struct {
int num_books,
max_books;
book *array;
} stack;
Da es in Deklaration einer array
als Array von Zeigern kein Vorteil ist, wenn man einfach Speicher für jedes Buch erstellen werden, können Sie auch erklären, nur Array als book *array;
und Speicher zuordnen für einige einigermaßen voraussichtliche Anzahl der Bücher, um damit zu beginnen. Dein create_stack
ist nicht weit weg, aber ich würde add_book
ein wenig anders machen, um den Stack zu erstellen, wenn es momentan NULL
und realloc
wie benötigt ist. So etwas wie die folgenden:
/** since add_book may create the stack, you must pass the address
* of the stack to add_book so that any changes to s are available
* back in the calling funciton.
*/
book *add_book (stack **s, char *title, int pages)
{
if (!title) return NULL; /* validate title */
if (!*s) *s = create_stack(); /* if stack NULL, create */
/* check num_books against max_books and realloc as required */
if ((*s)->num_books == (*s)->max_books) {
void *tmp = realloc ((*s)->array, ((*s)->max_books + NBOOKS) *
sizeof *((*s)->array));
if (!tmp) {
fprintf (stderr, "error: memory exhausted - realloc array.\n");
return NULL;
}
(*s)->array = tmp;
(*s)->max_books += NBOOKS;
}
/* allocate/copy title, assign pages, increment num_books */
(*s)->array[(*s)->num_books].title = strdup (title);
(*s)->array[(*s)->num_books].pages = pages;
((*s)->num_books)++;
/* change return as desired, I just return the address of the book
* to indicate success and provide a way to validate the add.
*/
return &((*s)->array[(*s)->num_books - 1]);
}
(note: der Kommentar, warum der Stapel der Funktion als stack **
übergeben wird)
Das sind im Grunde die Änderungen, die Sie benötigen würde Ihre Stapel Bücher erstellen das würde Ihnen erlauben, so viele Bücher hinzuzufügen, wie Sie möchten (bis Sie den Speicher Ihres Computers erschöpfen). das Beispiel zusammen setzen, können Sie so etwas wie die folgenden tun (Anmerkung: die Konstante NBOOKS
als Null größer sein müssen, können Sie Prüfungen hinzufügen, um sicherzustellen)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { NBOOKS = 10 };
typedef struct {
char *title;
int pages;
} book;
typedef struct {
int num_books,
max_books;
book *array;
} stack;
stack *create_stack();
book *add_book (stack **s, char *title, int pages);
void prn_stack (stack *s);
void free_stack (stack *s);
int main (void) {
stack *s1 = NULL; /* always initialize your pointers */
add_book (&s1, "Huck Finn", 631);
add_book (&s1, "Tom Sawyer", 582);
add_book (&s1, "The Quick Brown Fox", 1);
prn_stack (s1);
free_stack (s1);
return 0;
}
/** allocate stack and allocate storage for NBOOKS books */
stack *create_stack()
{
stack *s = calloc (1, sizeof *s);
if (!s) {
fprintf (stderr, "error: virtual memory exhausted - stack.\n");
exit (EXIT_FAILURE);
}
s->array = calloc (NBOOKS, sizeof *(s->array));
if (!s->array) {
fprintf (stderr, "error: virtual memory exhausted - array.\n");
exit (EXIT_FAILURE);
}
s->num_books = 0;
s->max_books = NBOOKS;
return s;
}
/** since add_book may create the stack, you must pass the address
* of the stack to add_book so that any changes to s are available
* back in the calling funciton.
*/
book *add_book (stack **s, char *title, int pages)
{
if (!title) return NULL; /* validate title */
if (!*s) *s = create_stack(); /* if stack NULL, create */
/* check num_books against max_books and realloc as required */
if ((*s)->num_books == (*s)->max_books) {
void *tmp = realloc ((*s)->array, ((*s)->max_books + NBOOKS) *
sizeof *((*s)->array));
if (!tmp) {
fprintf (stderr, "error: memory exhausted - realloc array.\n");
return NULL;
}
(*s)->array = tmp;
(*s)->max_books += NBOOKS;
}
/* allocate/copy title, assign pages, increment num_books */
(*s)->array[(*s)->num_books].title = strdup (title);
(*s)->array[(*s)->num_books].pages = pages;
((*s)->num_books)++;
/* change return as desired, I just return the address of the book
* to indicate success and provide a way to validate the add.
*/
return &((*s)->array[(*s)->num_books - 1]);
}
void prn_stack (stack *s)
{
if (!s) return;
printf ("\nThere are %d books in the stack:\n\n", s->num_books);
for (int i = 0; i < s->num_books; i++)
printf (" %2d. %-20s (%3d pages)\n", i, s->array[i].title, s->array[i].pages);
putchar ('\n');
}
void free_stack (stack *s)
{
if (!s) return;
for (int i = 0; i < s->num_books; i++)
free (s->array[i].title);
free (s->array);
free (s);
}
Beispiel Verwendung/Output
$ ./bin/bookstack
There are 3 books in the stack:
0. Huck Finn (631 pages)
1. Tom Sawyer (582 pages)
2. The Quick Brown Fox ( 1 pages)
Speichernutzung/Error Check
Einstellung NBOOKS
TO 2
Neuzuweisung zu zwingen und die Überprüfung mit valgrind
, finden Sie:
$ valgrind ./bin/bookstack
==15521== Memcheck, a memory error detector
==15521== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==15521== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==15521== Command: ./bin/bookstack
==15521==
There are 3 books in the stack:
0. Huck Finn (631 pages)
1. Tom Sawyer (582 pages)
2. The Quick Brown Fox ( 1 pages)
==15521==
==15521== HEAP SUMMARY:
==15521== in use at exit: 0 bytes in 0 blocks
==15521== total heap usage: 6 allocs, 6 frees, 153 bytes allocated
==15521==
==15521== All heap blocks were freed -- no leaks are possible
==15521==
==15521== For counts of detected and suppressed errors, rerun with: -v
==15521== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)
das ist, wie es sein sollte. Schauen Sie sich die Dinge an und lassen Sie es mich wissen, wenn Sie irgendwelche Fragen haben.
'Buch * Array [50];' erstellt ein * Array von Zeigern zu Buch 50 * nicht * 50 struct Buch *. –
'typedef struct stack * Stack;' ist ein irreführender 'typedef'. Verwenden Sie 'typedef struct stack Stack;' oder 'typedef struct stack * StackPtr;' –
@David Können Sie das bitte näher ausführen? – user6005857