C自动可扩展指针数组

C自动可扩展指针数组,c,pointers,C,Pointers,问题在页面末尾回答。完全工作的代码。 您好,我想在C中完成我在标题中要求的,但是,我不知道如何完成它。我在C++中这样做是得益于模板,但是L.C.这里是完全功能的C++代码: *现在我想知道是否可以用void指针模拟代码。问题是,我看到一个链接说void*应该避免,因为它可能会造成比它能解决的更多的麻烦 基本上,它是一个“智能数组”,存储指向变量本身的指针。 如果我知道每个指针的大小和指向的每个结构的大小,简单的malloc和realloc应该是正确的吗 typedef struct { v

问题在页面末尾回答。完全工作的代码。

您好,我想在C中完成我在标题中要求的,但是,我不知道如何完成它。我在C++中这样做是得益于模板,但是L.C.这里是完全功能的C++代码:

*现在我想知道是否可以用void指针模拟代码。问题是,我看到一个链接说void*应该避免,因为它可能会造成比它能解决的更多的麻烦

基本上,它是一个“智能数组”,存储指向变量本身的指针。 如果我知道每个指针的大小和指向的每个结构的大小,简单的malloc和realloc应该是正确的吗

typedef struct
{
  void **list;

  // internal
  int last_item_index;
  size_t element_size; // size of each pointer
  int elements;        // number of currently allocated elements
  int total_size;      // >= #elements so that we don't have to always call malloc
  int tweak_request_size; // each time the list grows we add this # of elements

} List;
// a shot at an addCopy function
// it deepcopies the object you pass in
List_addCopy(List *db, void *ptr_to_new_element)
{
  ... // grow **list
  // alloc and copy new element
  db->list[db->last_item_index+1] = malloc(element_size); // WORKS?
  // HOW TO COPY THE ELEMENT TO HERE IF IT IS A STRUCTURE FOR INSTANCE???
  ...
}

or
// a shot at an assign function 
// (allocate the elements yourself then pass the pointer to the List)
List_assign(List *db, void *ptr_to_new_element)
{
  db->List = realloc(db->List, element_size*(elements+tweak_request_size));
  db->List[db->last_item_index+1] = ptr_to_new_element;
}

// Usage example

List db; // our database
struct funky *now = (funky*)malloc(sizeof(funky));

funky->soul = JamesBrown;

List_addCopy(db, funky);

if (list[0]->soul == JamesBrown)
  puts("We did It! :D");
如果我把所有的东西都分配到外面,然后把指针传给列表,我想唯一的问题就是空**

可以添加列表吗?仅使用对元素进行alloc和/或复制的回调

列表分配是否可行?我不想有太多的工作,最终得到不可靠的软件


非常感谢,也很抱歉在写作中遇到了麻烦:p

您可以通过以下方式避免
void*

#include <stdio.h>
#include <stdlib.h>

#define List(T) \
    typedef struct { \
        T** items; \
        int count;  \
    } List_ ## T ;\
    \
    List_ ## T * List_ ## T ## _New() { \
        List_ ## T * list = (List_ ## T *) malloc(sizeof(List_ ## T)); \
        list->count = 0; \
        return list; \
    } \
    \
    void List_ ## T ## _Add(List_ ## T *list, T * data) { \
        printf("%d\n", ++list->count); \
    } \
    void List_ ## T ## _Del(List_ ## T *list, int index) { \
        printf("%d\n", --list->count); \
    }

/* define just one list per type */
List(int);
List(double);

int main()
{
    int a, b, c;
    double d, e;
    List_int *l1;
    List_double *l2;

    l1 = List_int_New();
    List_int_Add(l1, &a);
    List_int_Add(l1, &b);
    List_int_Add(l1, &c);
    List_int_Del(l1, 0);
    List_int_Del(l1, 0);
    List_int_Del(l1, 0);
    free(l1);

    l2 = List_double_New();
    List_double_Add(l2, &d);
    List_double_Add(l2, &e);
    List_double_Del(l2, 0);
    List_double_Del(l2, 0);
    free(l2);

    return 0;
}
#包括
#包括
#定义列表(T)\
类型定义结构{\
T**项目\
整数计数\
}列表###T\
\
List##T*List#T#T#u New(){\
List#T*List=(List#T*)malloc(sizeof(List#T))\
列表->计数=0\
退货清单\
} \
\
无效列表##T##u添加(列表##T*列表,T*数据){\
printf(“%d\n”,++列表->计数)\
} \
无效列表35;#####Del(列表###T*List,int索引){\
printf(“%d\n”,--list->count)\
}
/*每种类型只定义一个列表*/
名单(国际);
名单(双份);
int main()
{
INTA、b、c;
双d,e;
列表_int*l1;
列表双*l2;
l1=列表\内部\新建();
列表\内部\添加(l1和a);
列表添加(l1和b);
列表\内部\添加(l1和c);
列表(l1,0);
列表(l1,0);
列表(l1,0);
自由(l1);
l2=列表双新();
列表双加(l2和d);
列表双加(l2和e);
列表双数据集(l2,0);
列表双数据集(l2,0);
自由(l2);
返回0;
}

这是一个穷人的模板=)

我使用了特立尼达的方法,因为我不确定
void**
是否有效,这是一个非常好的xD

它工作得很完美,但要避免循环依赖关系(包括另一个导致“多重引用”的标题)而不妨碍太多的接口,这很复杂,所以我放弃了这种方法,尽管我也上传了@SourceForge,然后我再次制作了所有内容,这次使用了空指针,它工作得很完美;)不必担心包含两次标题等,只需工作即可

顺便说一句,这里有一个链接,可以随意使用:


如果有任何疑问,请使用帮助论坛,当我有时间时,我会将其记录下来,但目前我正在将其用于我的项目。

如果您知道元素的大小,并且它是一个简单的平面数据结构(没有指向任何也需要复制的内容的指针),只需
memcpy
就可以了。@Pemdas:我想我确实提到过。那不会造成问题吧?使用void**?我看到一条帖子说,应该避免使用void**,因为结果可能是混合的:谢谢谢谢!我有了这个想法,它似乎很容易使用,只是很难实现,但我想它很好,因为你只需要做一次;)我不认为有那么难,只需要一些额外的
\
\
。调试它和跟踪编译时错误可能很困难,我认为最好像
List\u int
那样实现它,并首先测试它,然后将它变成一个“模板”。这种方法的另一个问题是列表类型参数不能是指针,因为在生成过程名称时,编译器不会喜欢包含
*
的名称,但这可以像我一样通过使指针隐式来解决。