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

时间:2014-05-02 17:03:26

标签: c arrays pointers dynamic-memory-allocation

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

那就是说,我确定它非常基础,但我被卡住了。代码编译,但是当我运行可执行文件时它会冻结。 (我使用minGW gcc,如果重要的话。我现在根本不清楚如何使用gdb。)

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

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

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);

}

3 个答案:

答案 0 :(得分:3)

编辑更清楚一点。

问题是你的init例程正在使用&#34; vector&#34;的副本。并且是malloc进入该副本而不是原始向量指针。在初始化返回时,您松开了指向内存块的指针。

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

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

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

initialize_vector(&vector);

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

答案 1 :(得分:2)

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

足够的理论,以下是如何修复代码:

void initialize_vector( int **vector );

initialize_vector(&vector);

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

}

答案 2 :(得分:1)

在其他回复的添加中,我建议采用另一种方法。

假设至少符合C99的编译器,我宁愿建议将分配的大小保留在以flexible array member结尾的结构中(参见this),如:

 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)等等。或者将它们作为三个单独的形式传递给类似的例程,然后你需要传递它们的地址因为例程会改变它们,例如您将create_dynamic_vector(unsigned *countptr, unsigned *sizeptr, int**vectarrptr)等调用的create_dynamic_vector(&mycount, &mysize, &myvectarr);

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