C:向动态分配的数组添加元素

我试图通过谷歌搜索一个解决方案:我找不到任何有帮助的东西; 它甚至看起来好像我正确地这样做了。 我能找到的关于通过函数发送动态分配的数组的唯一页面处理的是一个结构内部的数组,当然是标量,所以表现不同。 我现在不想使用结构 – 我正在尝试学习DAM并使用指针和函数。

那就是说,我确信这是非常基本的,但我被困住了。 代码编译,但是当我运行可执行文件时它会冻结。 (我正在使用minGW gcc,如果这很重要。而且我现在还不清楚如何使用gdb。)

这是代码(最终,我希望整个代码是类似ArrayList的数据结构):

#include  #include  void add( int element, int *vector); void display_vector( int *vector ); void initialize_vector( int *vector ); int elements = 0; int size = 10; int main(void) { int *vector = 0; initialize_vector(vector); add(1, vector); //add(2, vector); //add(3, vector); //add(4, vector); //add(5, vector); //add(6, vector); //add(7, vector); //add(8, vector); //add(9, vector); //add(10, vector); //add(11, vector); display_vector(vector); return 0; } void add( int element, int *vector) { vector[elements++] = element; return; } void display_vector( int *vector ) { int i; for( i = 0; i < elements; i++) { printf("%2d\t", vector[i]); if( (i + 1) % 5 == 0 ) printf("\n"); } printf("\n"); return; } void initialize_vector( int *vector ) { vector = (int *)malloc(sizeof(int) * size); } 

编辑更清楚一点。

问题是你的init例程正在使用“vector”的副本,并且是malloc’ing到该副本而不是原始向量指针。 您从初始化返回时松开指向内存块的指针。

将向量的参数更改为此函数中的句柄(指针指针)

 void initialize_vector( int **vector ) { *vector = (int *)malloc(sizeof(int) * size); } 

然后将对init的调用更改为此

 initialize_vector(&vector); 

我没有编译它,但它应该修复代码。

在C中,函数参数按值传递,这意味着传递给函数的每个参数都有一个本地副本,如果更改函数中的参数,则只更改该参数的本地副本。 因此,如果要更改函数中参数的值,则需要将其地址传递给该函数,取消该地址并将其分配给该函数中的结果。

足够的理论,这里是如何修复您的代码:

 void initialize_vector( int **vector ); initialize_vector(&vector); void initialize_vector( int **vector ) { *vector = (int *)malloc(sizeof(int) * size); } 

除了其他答复,我建议采用另一种方法。

假设至少符合C99标准的编译器,我宁愿建议将分配的大小保留在以灵活数组成员结尾的结构的成员中 (参见此内容 ),如:

  typedef struct vector_st { unsigned count; // used length unsigned size; // allocated size, always >= length int vectarr[]; } Vector; 

然后你将构建这样一个矢量

  Vector* make_vector (unsigned size) { Vector* v = malloc(sizeof(Vector)+size*sizeof(int)); if (!v) { perror("malloc vector"); exit (EXIT_FAILURE); }; memset (v->vectarr, 0, size*sizeof(int)); v->count = 0; v->size = size; } 

要将元素添加到矢量中,请返回原始矢量或增长的矢量:

 Vector* append_vector (Vector*vec, int elem) { assert (vec != NULL); unsigned oldcount = vec->count; if (oldcount < vec->size) { vec->vectarr[vec->count++] = elem; return vec; } else { unsigned newsize = ((4*oldcount/3)|7) + 1; Vector* oldvec = vec; vec = malloc(sizeof(Vector)+newsize*sizeof(int)); if (!vec) { perror("vector grow"); exit(EXIT_FAILURE); }; memcpy (vec->vectarr, oldvec->vectarr, oldcount*sizeof(int)); memset (vec->vectarr + oldcount, 0, (newsize-oldcount) * sizeof(int)); vec->vectarr[oldcount] = elem; vec->count = oldcount+1; vec->size = newsize; free (oldvec); return vec; } } 

你可以编码:

 Vector* myvec = make_vector(100); myvec = append_vector(myvec, 35); myvec = append_vector(myvec, 17); for (int i=0; i<150; i++) myvec = append_vector(myvec, i*2); 

要释放这样的载体,只需使用free(myvec);


如果你真的不想使用任何struct你应该在单独的变量中保存向量的使用长度,向量的分配大小,动态分配数组的指针:

  unsigned used_count; // useful "length" unsigned allocated_size; // allocated size, always not less than used_count int *dynamic_array; // the pointer to the dynamically allocated array 

如果您希望能够管理多个向量,则将上述有用长度,已分配大小和动态数组打包到一些struct dynamic_array_st (其指针将传递给适当的例程,如make_dynamic_vector(struct dynamic_array_st*)append_dynamic_vector(struct dynamic_array_st*, int)等....或者将它们作为三个单独的forms传递给类似的例程,然后你需要传递它们的地址,因为例程会改变它们,例如create_dynamic_vector(unsigned *countptr, unsigned *sizeptr, int**vectarrptr)你将调用create_dynamic_vector(&mycount, &mysize, &myvectarr); 等等

我认为灵活的arrays成员仍然是最干净的方法。