动态增加c中数组(int *)的大小 [英] dynamically increase size of array (int*) in c

查看:45
本文介绍了动态增加c中数组(int *)的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想动态地将数字添加到c中的数组.我的想法是分配一个大小为1的新数组,添加数字,释放根数组,然后将指针从temp更改为根数组.像这样:

  void addNumber(int * a,int *大小,int号){*大小= *大小+1;int * temp =(int *)(calloc(* size,sizeof(int)));int i,j = 0;for(i = 0; i< * size-1; i ++){if(a [i]< number){printf("add ai");temp [j] = a [i];j ++;} 别的 {printf(增加号码");temp [j] =数字;}}if(j!= * size){printf(添加新号码");temp [j] =数字;}免费(a);a =温度;}int main(int argc,char * argv []){整数n = 10;int * a;int大小= 1;a =(int *)(calloc(1,sizeof(int)));a [0] = 1;if(!contains(a,size,2)){addNumber(a,& size,2);}printArray(a,size);返回0;} 

问题是在addNumber函数中代码可以工作,并且* a具有新数组的正确值.但是在主函数中,数组* a的值为1,0.因此,不会添加新的插入值2.为什么?无法找到原因.

解决方案

您正在寻找的是 realloc() .它可以用来增加或缩小内存,同时保留其内容.

 /*数组现在为sizeof(int)* new_size个字节*/array = realloc(array,sizeof(int)* new_size); 

realloc()可能会更改现有的内存分配,或者可能会分配一个全新的内存块.这就是为什么将结果重新分配给要重新分配的东西很重要的原因.

但是,如果 addNumber()通过创建新的内存来重新分配数组,则 main()不会知道它.出于同样的原因,这是行不通的.

  void增量Number(int num){num = num + 1;} 

int num 是一个按值传递的数字.如果希望它反映在调用方中,则需要将其作为指针传递.

  void增量Number(int * num){* num = * num +1;} 

指针是相同的方式.他们仍然是数字. int * a 通过值传递一个指针.如果您在 addNumber 中更改 a ,则呼叫者将不会看到它.和以前一样,您需要将其作为指针传递.指向这样使用的指针的指针称为双指针

  void addNumber(int ** array_ptr,size_t * array_size,size_t type_size,int number){/*增加大小并确保气泡*/* array_size = * array_size + 1;/* realloc可能会增加内存,或者可能会分配新的内存无论哪种方式,将结果分配回其原始变量通过取消引用双指针.*/* array_ptr = realloc(* array_ptr,* array_size * type_size);/*由于它是双指针,因此在使用之前我们必须先对其取消引用它作为一个数组*/(* array_ptr)[* array_size-1] =数字;} 

(请注意,我还传入了数组中元素的大小,这是不能假定的.)

这是通过将指针传递给数组来调用的.

  addNumber(& a,& size,sizeof(int),5); 

在那之后,一切都一样.

  for(int i = 0; i< size; i ++){printf(%d",a [i]);}puts("); 


最终,您将需要通过在结构中使用数组,大小和类型来改进此功能,以便可以在整洁的包中传递它.

  typedef struct {int *数组;size_t大小;} IntArray; 

这是一项很好的练习,您会学到很多东西,并且会养成很多关于静态内存的坏习惯.但是正确而有效地执行动态数据结构是困难的(例如,一次分配一个额外的插槽效率很低).

有很多提供这种动态结构的库.因此,继续练习作为一个练习,但是对于真实代码,请使用诸如 Gnome Lib的库.

i want to dynamically add numbers to an array in c. My idea is to just allocate a new array with size + 1, add the number, free the root array and change the pointer from the temp to the root array. Like this:

void addNumber(int* a, int* size, int number)
{
    *size = *size + 1;
    int* temp = (int*)(calloc(*size, sizeof(int)));
    int i, j = 0;
    for(i = 0; i < *size-1; i++) {
        if(a[i] < number) {
            printf("add ai");
            temp[j] = a[i];
            j++;
        } else {
            printf("add number");
            temp[j] = number;
        }
    }
    if(j != *size) {
        printf("add new number");
        temp[j] = number;
    }
    free(a);
    a = temp;
}

int main(int argc, char* argv[])
{
    int n = 10;
    int* a;
    int size = 1;

    a = (int*) (calloc(1, sizeof(int)));
    a[0] = 1;

    if(!contains(a, size, 2)) {
        addNumber(a, &size, 2);
    }

    printArray(a,size);

    return 0;
}

The problem is that in the addNumber function the code works and the *a has the right values of the new array. But in the main function the array *a has the values 1,0. So the new inserted value 2 is not added. Why? Can't get the reason.

解决方案

What you're looking for is realloc(). It can be used to grow or shrink memory while retaining its contents.

/* array is now sizeof(int) * new_size bytes */
array = realloc(array, sizeof(int) * new_size);

realloc() might change the existing memory allocation, or it might allocate a whole new block of memory. This is why it's important to reassign the result back to the thing being reallocated.

But if addNumber() reallocates the array by making new memory, main() won't know it. This is for the same reason this doesn't work.

void incrementNumber(int num) {
    num = num + 1;
}

int num is a number that gets passed by value. If you want it to be reflected in the caller, you need to pass it as a pointer.

void incrementNumber(int *num) {
    *num = *num + 1;
}

Pointers are the same way. They're still numbers. int *a passes a pointer by value. If you change a in addNumber it won't be seen by the caller. Just like before, you need to pass it as a pointer. A pointer to a pointer used like this is known as a double pointer.

void addNumber( int **array_ptr, size_t *array_size, size_t type_size, int number ) {
    /* Increment the size and make sure that bubbles up */
    *array_size = *array_size + 1;

    /* realloc might grow the memory, or it might allocate new memory
       either way, assign the result back to its original variable
       by dereferencing the double pointer.
     */
    *array_ptr = realloc(*array_ptr, *array_size * type_size);

    /* Since it's a double pointer, we have to first dereference it before using
       it as an array */
    (*array_ptr)[*array_size - 1] = number;
}

(Note that I also pass in the sizeof the elements in the array, that can't be assumed).

This is called by passing a pointer to the array.

addNumber(&a, &size, sizeof(int), 5);

After that, everything is the same.

for( int i = 0; i < size; i++ ) {
    printf("%d ", a[i]);
}
puts("");


Eventually you'll want to improve this by having the array, size, and type in a struct so you can pass that around in a neat package.

typedef struct {
    int *array;
    size_t size;
} IntArray;

This is great to do as an exercise, you'll learn a lot and kick a lot of bad habits about static memory. But doing dynamic data structures correctly and efficiently is difficult (for example, allocating one extra slot at a time is very inefficient).

There are many, many libraries out there which provide such dynamic structures. So continue with this as an exercise, but for real code use a library such as Gnome Lib.

这篇关于动态增加c中数组(int *)的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆