C 如何访问结构中的结构数组?
我有以下两种结构:C 如何访问结构中的结构数组?,c,arrays,struct,stack,C,Arrays,Struct,Stack,我有以下两种结构: typedef struct stack * StackPtr; typedef struct book * BookPtr; struct book { char *title; int pages; }; struct stack { int num_books; Book array[50] // changed from Book *array[50] }; 以下是我初始化每个结构的方式: StackPtr create_stac
typedef struct stack * StackPtr;
typedef struct book * BookPtr;
struct book {
char *title;
int pages;
};
struct stack {
int num_books;
Book array[50] // changed from Book *array[50]
};
以下是我初始化每个结构的方式:
StackPtr create_stack(void) {
StackPtr s = malloc(sizeof(struct stack));
s->num_books = 0;
return s;
}
BookPtr create_book(char *title, int pages) {
BookPtr b = malloc(sizeof(struct book));
b->title = strdup(title);
b->pages = pages;
return b;
}
我正在尝试使用堆栈结构中的数组访问该书的标题和页面。我就是这样做的:
例如,如果我想访问和修改结构中最后一本书的标题和页面,我可以这样做:
(s->array[s->num_books-1])->title = strdup(new_title);
(s->array[s->num_books-1])->pages = new_pages;
但是,我遇到了以下错误:
error: member reference base type 'Book' (aka 'struct book *') is not a structure or union
(s->array[s->num_books-1])->title = strdup(new_title);
~~~~~~~~~~~~~~~~~~~~~~~~~~^ ~~~~~
error: incomplete definition of type 'struct book'
(s->array[s->num_books-1])->title = strdup(new_title);
~~~~~~~~~~~~~~~~~~~~~~~~~~^
编辑:在我从
Book*数组[50]中删除指针之后代码>我现在遇到此错误:
error: member reference base type 'Book' (aka 'struct book *') is not a structure or union
(s->array[s->num_books-1])->title = strdup(new_title);
~~~~~~~~~~~~~~~~~~~~~~~~~~^ ~~~~~
error: incomplete definition of type 'struct book'
(s->array[s->num_books-1])->title = strdup(new_title);
~~~~~~~~~~~~~~~~~~~~~~~~~~^
我认为这是因为main无法查看书籍结构的问题,所以我停止使用头文件,将所有内容都放在一个文件中,但这没有帮助
我还认为我没有正确初始化堆栈
当我尝试在create_stack函数中初始化数组时,如下所示:
s->array = malloc(sizeof(BookPtr) * 50); //inside create_array function
这是我得到的错误:
array type 'BookPtr *[50]' is not assignable
您已经将Book
定义为指向struct Book
的指针,然后定义了Book
类型的指针数组,这意味着它是指向struct Book
的指针数组
在数组定义中将Book
定义为struct Book
,或者从Book
之后删除指针。通常是前者,因为您没有清楚地将其命名为BookPtr
我无法评论,因此我将详细阐述大卫·C·兰金的评论。你对数组的定义不起作用
您可能应该使用以下选项之一
这将为您提供最多可容纳50本书的书籍阵列:
Book array[50];
这将为您提供一个指向书籍数组的指针,该数组没有大小限制,但需要更多开销
Book *array;
如果使用后者,则必须创建阵列,跟踪其当前长度,并在填充后使其变大(请参见)。目前尚不清楚是否解决了此问题,因此也许一个简短的示例会有所帮助。无论您是在开始时为array
中的X个图书创建存储,还是将array
创建为指向图书的X个指针数组,您都需要某种方法来确保添加的图书不会超过存储量。处理这一问题的明显方法是向堆栈
结构添加一个附加变量,用于跟踪数组
中的存储(或可用指针数),然后根据需要添加realloc
数组
。要跟踪可用的数组中的空间,只需添加另一个计数器,例如max\u books
,即可
enum { NBOOKS = 10 };
typedef struct {
char *title;
int pages;
} book;
typedef struct {
int num_books,
max_books;
book *array;
} stack;
由于在为每本书创建存储时,将数组
声明为指针数组没有任何好处,因此您也可以将数组声明为book*array编码>并为开始时合理预期的图书数量分配存储空间。您的create_stack
已经不远了,但是如果当前NULL
和realloc
是需要的,我会做一些不同的add_book
来创建堆栈。如下所示:
/** 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]);
}
(注意:关于堆栈作为stack**
传递给函数的原因的注释)
这些基本上就是创建一堆书所需的更改,这些更改允许您添加任意数量的书(直到耗尽计算机内存)。将示例放在一起,您可以执行如下操作(注意:常量NBOOKS
必须大于零,您可以添加支票以确保)
内存使用/错误检查
将NBOOKS
设置为2
以强制重新分配并使用valgrind
进行检查,您将发现:
$ 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)
应该是这样的。仔细检查一下,如果有任何问题,请告诉我。Book*array[50]代码>创建指向book 50而非50 struct book的指针数组。typedef struct stack*stack
是一种误导性的typedef
。使用typedef结构堆栈代码>或typedef结构堆栈*StackPtr
@David你能详细说明一下吗?当然,如果你想创建一个包含50个struct book的数组,请使用book array[50]代码>,然后您将访问类似于s->book[i]的内容。标题
。如果您创建一个指向struct book的未初始化指针数组(例如book*数组[50];
),则必须为每个指针分配内存,然后才能将值分配给成员等(可以这样做,您只需管理每个书的内存分配)决不能typedef
指针!我这样做了,但是我在这一行得到了类型“structbook”的不完整定义:(s->array[s->num_books-1])->title=strdup(title)代码>我不明白。您是否可以编辑原始帖子以添加新代码而不删除原始代码?