这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
unsigned long sz;
char *item;
} itemset;
void additem(char** ram,itemset** items,char* thing){
unsigned long sz=strlen(thing);
if (sz > 20000 || sz < 1){return;}
(**items).item=*ram;
(*ram)+=sz;
(**items).sz=sz;
memcpy((char*)((**items).item),thing,sz);
(*items)++;
}
void showitems(itemset* items){
unsigned long ct=1;
while(items->sz > 0){
char buf[items->sz+2];
memset(buf,0,items->sz+2);
memcpy(buf,items->item,items->sz);
printf("Item %d: size: %d = %s\n",ct,items->sz,buf);
items++;ct++;
}
}
int main(){
char itembuf[50000];
itemset* myitems=(itemset*)itembuf;
char* mp=calloc(1,100000);
char* wmp=mp;
itemset* items=myitems;
additem(&wmp,&myitems,"Test");
additem(&wmp,&myitems,"Tests");
additem(&wmp,&myitems,"Tester");
additem(&wmp,&myitems,"Testing");
showitems(items);
printf("%s\n",mp);
free(mp);
}
执行后,屏幕上会显示正确的输出,如下所示:
Item 1: size: 4 = Test
Item 2: size: 5 = Tests
Item 3: size: 6 = Tester
Item 4: size: 7 = Testing
TestTestsTesterTesting
要使additem函数正常工作,它需要两个自动更新的指针。一个用于更新文本的ram内存地址,另一个用于更新struct的堆栈内存地址。
我想知道是否有更新函数的方法并调用它,以便只传入一个指针并进行更新。例如:
additem(&stuff,"Test");
我希望整体程序功能仍然相同,但我不想在结构中使用固定字符数组,因为这会浪费宝贵的内存。
答案 0 :(得分:0)
在struct
中捆绑属于item-set-cum-char-buffer的所有内容,然后将指向该结构的指针传递给您的函数。如果不修改结构,例如打印项目集时,请传递const
指针。
您还应该提供初始化和清理项集的函数,以便cleint代码不必担心集的实现细节。
您的代码可能如下所示:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct{
size_t length;
char *str;
} Item;
typedef struct {
size_t bufsize; /* fixed size of the char buffer */
size_t buflen; /* currently used size of buffer */
char *buf;
size_t maxitem; /* max. number of items */
size_t count; /* current number of items */
Item *item;
} Itemset;
int iset_init(Itemset *iset, size_t maxitem, size_t bufsize)
{
iset->buflen = 0;
iset->bufsize = bufsize;
iset->buf = malloc(bufsize);
iset->count = 0;
iset->maxitem = maxitem;
iset->item = malloc(maxitem * sizeof(*iset->item));
if (iset->item && iset->buf) return 0;
free(iset->item);
free(iset->buf);
return -1;
}
int iset_add(Itemset *iset, char* str)
{
size_t sz = strlen(str);
if (iset->count >= iset->maxitem) return -1;
if (iset->buflen + sz + 1 > iset->bufsize) return -1;
iset->item[iset->count].str = &iset->buf[iset->buflen];
iset->item[iset->count].length = sz;
iset->count++;
strcpy(&iset->buf[iset->buflen], str);
iset->buflen += sz + 1;
printf("%zu\n", iset->buflen);
return 0;
}
void iset_show(const Itemset *iset)
{
size_t i;
printf("%zu items:\n", iset->count);
for (i = 0; i < iset->count; i++) {
printf("[%d] %s (%zu letters)\n",
i, iset->item[i].str, iset->item[i].length);
}
}
void iset_free(Itemset *iset)
{
if (iset) {
free(iset->buf);
free(iset->item);
}
memset(iset, 0, sizeof(*iset));
}
客户端代码看起来会更整洁:
int main()
{
Itemset iset;
if (iset_init(&iset, 50, 500) < 0) {
fprintf(stderr, "Couldn't initialise dict.");
exit(1);
}
iset_add(&iset, "Test");
iset_add(&iset, "Tests");
iset_add(&iset, "Tester");
iset_add(&iset, "Testing");
iset_show(&iset);
iset_free(&iset);
return 0;
}