c语言中的链式结构
我希望实现一个简单的数据结构,比如链表,但我还不需要那么复杂的东西,或者我需要吗 假设我有一本书的数据结构c语言中的链式结构,c,pointers,memory-management,C,Pointers,Memory Management,我希望实现一个简单的数据结构,比如链表,但我还不需要那么复杂的东西,或者我需要吗 假设我有一本书的数据结构 typedef struct { char* name; size_t number; } book; 我想把这些附加到越来越多的书中,在记忆中应该是这样的 ------------------------ | 0 | 1 | 2 | 3 | ...... ------------------------ 因为我不做任何花哨的事情,除了添加一堆书,从不改变顺序,只在程序
typedef struct {
char* name;
size_t number;
} book;
我想把这些附加到越来越多的书中,在记忆中应该是这样的
------------------------
| 0 | 1 | 2 | 3 | ......
------------------------
因为我不做任何花哨的事情,除了添加一堆书,从不改变顺序,只在程序结束时释放书,所以我不需要链表的所有功能
我试图用这样的双指针来创建书籍的原始结构
public book** add_bookd(book** books, book* b) {
static int index = -1;
int count;
index++;
count = index + 1;
book** books = realloc(books, sizeof(book*)*count);
books[index] = calloc(1, sizeof(book));
copy_bookd(books[index], b); //this is just a series of memcopy
//since i have POD data types
return books;
}
我试过用一个非常简单的字符,但我得到了seg错误
char** double_pointer(char** a, char* b) {
static int index = -1; int count;
index++;
count = index + 1;
a = realloc(a, sizeof(char*)*count);
for(int i = 0; i < index; i++) {
a[i] = calloc(1, sizeof(char));
a[i] = b;
printf("%s\n",a[i]);
}
return a;
}
char** tmp = calloc(1, sizeof(char*));
for(int i = 0; i < 3; i++) {
double_pointer(tmp, "a");
//printf("%s\n",tmp)); //seg faults here
}
试图访问tmp[0]gdb表示无法访问0x0处的内存。这些行:
book** books = realloc(books, sizeof(book*)*count);
books[index] = calloc(1, sizeof(book));
copy_bookd(books[index], b);
显示出一些问题,特别是缺少错误检查
建议:
book* temp = realloc(*books, sizeof(book*)*count);
if( temp != NULL )
{ // then, realloc successful
*books = temp;
(*books)[index] = calloc(1, sizeof(book));
if( (*books)[index] != NULL )
{ // then, calloc successful
copy_bookd((*books)[index], b);
}
else
{
// handle calloc failure
}
}
else
{
// handle realloc failure
}
这些线路:
book** books = realloc(books, sizeof(book*)*count);
books[index] = calloc(1, sizeof(book));
copy_bookd(books[index], b);
显示出一些问题,特别是缺少错误检查
建议:
book* temp = realloc(*books, sizeof(book*)*count);
if( temp != NULL )
{ // then, realloc successful
*books = temp;
(*books)[index] = calloc(1, sizeof(book));
if( (*books)[index] != NULL )
{ // then, calloc successful
copy_bookd((*books)[index], b);
}
else
{
// handle calloc failure
}
}
else
{
// handle realloc failure
}
所以你正在寻找一种可能性来存储一些书,你可能只会添加一些?这确实可以通过一种与您已有的方法非常相似的方法来实现。但让我们从头开始: 基本上,您在内存中的某个位置存储一个书籍“数组”,即在一个连续的内存位置中存储多个
struct book
。可以使用指向第一本书的指针指向该数组:
struct book * books;
不知何故,您还需要知道该数组的结束位置。因此,我看到的两种可能性是要么使用sentinel值(类似于C字符串对'\0'
的作用),要么只跟踪数组的大小。我会选择后者:
size_t count;
由于您不想迷路,我们使用结构化编程技术将这两条信息绑定在一起:
struct bookstore {
struct book * books;
size_t count;
};
为了与这样的商店合作,普通的操作应该放在花哨的名字后面。这叫做抽象,可能是编程时最重要的事情。在C中执行此操作的设备是函数。从一开始初始化空存储:
char init_store(struct bookstore * store) {
assert(store != NULL);
store->count = 0;
store->books = malloc(0);
return (store->books == NULL) ? 0 : 1;
}
并添加其双重功能,即“完成”存储的功能:
这些函数仅在已有的struct bookstore
实例上运行。您可以在堆栈或堆上分配它们(通过malloc
,不要忘记释放
)
现在进入关键部分:添加一本书。为此,您需要放大“数组”,以便能够在其中存储新项目。这是使用realloc
完成的。然后,您只需将书复制到空闲位置即可添加:
char add_book(struct bookstore * store, struct book book) {
assert(store != NULL);
assert(store->books != NULL);
struct book * books =
realloc(store->books, (store->count + 1) * sizeof(struct book));
if (books == NULL) {
return 0;
}
books[store->count] = book;
store->books = books;
store->count += 1;
return 1;
}
这就是我的方法,尽管还有很多优化的空间。但是请注意,上面的代码未经测试
该方法基本上与您的方法相同:您将使用指向(包含)书籍指针的指针。重要的区别是大小也会被存储。您的代码为此使用了一个静态局部变量,这本质上限制了您只有一个书籍“列表”。作为一个建议:避免像地狱一样的全局或静态。所以你正在寻找一种可能性来存储一些书,你可能只会添加到其中?这确实可以通过一种与您已有的方法非常相似的方法来实现。但让我们从头开始: 基本上,您在内存中的某个位置存储一个书籍“数组”,即在一个连续的内存位置中存储多个
struct book
。可以使用指向第一本书的指针指向该数组:
struct book * books;
不知何故,您还需要知道该数组的结束位置。因此,我看到的两种可能性是要么使用sentinel值(类似于C字符串对'\0'
的作用),要么只跟踪数组的大小。我会选择后者:
size_t count;
由于您不想迷路,我们使用结构化编程技术将这两条信息绑定在一起:
struct bookstore {
struct book * books;
size_t count;
};
为了与这样的商店合作,普通的操作应该放在花哨的名字后面。这叫做抽象,可能是编程时最重要的事情。在C中执行此操作的设备是函数。从一开始初始化空存储:
char init_store(struct bookstore * store) {
assert(store != NULL);
store->count = 0;
store->books = malloc(0);
return (store->books == NULL) ? 0 : 1;
}
并添加其双重功能,即“完成”存储的功能:
这些函数仅在已有的struct bookstore
实例上运行。您可以在堆栈或堆上分配它们(通过malloc
,不要忘记释放
)
现在进入关键部分:添加一本书。为此,您需要放大“数组”,以便能够在其中存储新项目。这是使用realloc
完成的。然后,您只需将书复制到空闲位置即可添加:
char add_book(struct bookstore * store, struct book book) {
assert(store != NULL);
assert(store->books != NULL);
struct book * books =
realloc(store->books, (store->count + 1) * sizeof(struct book));
if (books == NULL) {
return 0;
}
books[store->count] = book;
store->books = books;
store->count += 1;
return 1;
}
这就是我的方法,尽管还有很多优化的空间。但是请注意,上面的代码未经测试
该方法基本上与您的方法相同:您将使用指向(包含)书籍指针的指针。重要的区别是大小也会被存储。您的代码为此使用了一个静态局部变量,这本质上限制了您只有一个书籍“列表”。作为建议:避免像地狱一样的全局或静态。有许多方法可以跟踪许多结构。最简单的动态结构是结构的动态数组。同样的内存管理方法也适用,但您可以添加另一个外部结构,以帮助保存与该图书集合相关的信息。例如,如果您有多个感兴趣的收藏,您可以做类似的事情:
typedef {
size_t nbooks;
size_t allocsz;
char colname[16];
struct {
char* name;
size_t number;
} book;
} collection;
这样的方法允许一个结构保存它包含的图书数量、当前分配大小和收藏的唯一名称(例如小说、非小说等)
你可以考虑这样的事情是否会增加足够的额外数据来满足你的需求。对于结构数组的基本处理,动态声明