在C中调整结构中的数组大小

时间:2015-04-15 23:52:02

标签: c arrays pointers

我在围绕正确使用C中的数组指针时遇到了问题。

我正在开发的项目是构建一个简单的动态数组以及随之而来的功能。但是我似乎无法找到正确的语法/函数来动态更新数组大小。以下是相关代码:

阵列创建:

    struct DArray
{
    TYPE *data;     /* pointer to the data array */
    int size;       /* Number of elements in the array */
    int capacity;   /* capacity ofthe array */
};


void initDArray(DArray *v, int capacity)
{
    assert(capacity > 0);
    assert(v!= 0);
    v->data = (TYPE *) malloc(sizeof(TYPE) * capacity);
    assert(v->data != 0);
    v->size = 0;
    v->capacity = capacity;
}


DArray* createDArray(int cap)
{
    assert(cap > 0);
    DArray *r = (DArray *)malloc(sizeof( DArray));
    assert(r != 0);
    initDArray(r,cap);
    return r;
}

问题在于目前的非工作形式:

    void _DArraySetCapacity(DArray *v, int newCap)
{

    TYPE * newptr = createDArray(newCap);
    newptr = (TYPE *) malloc(sizeof(TYPE) * newCap);
    v->capacity = newCap;
    v->data = newptr;

}

我的方法是创建具有增加的内存分配的临时指针,然后将现有日期复制到它并将数据指针指向新位置。我怀疑我可能会以完全错误的方式看待这个问题。

任何帮助提示或指示(双关语)都将不胜感激。提前谢谢。

4 个答案:

答案 0 :(得分:1)

如何使用realloc

  

C库函数void * realloc(void * ptr,size_t size)尝试调整先前通过调用malloc或calloc分配的ptr指向的内存块的大小。

答案 1 :(得分:1)

幸运的是,你不需要自己移动记忆:realloc为你做这件事。

在您的情况下,典型的用法是:

v->capacity = newCap;
v->data = realloc(v->data, newCap * sizeof *v->data); /* same as sizeof(TYPE) */

请注意,您不必(也不应该)强制转换malloc / calloc或realloc的结果。

答案 2 :(得分:0)

使用realloc()

See this question and answer更好地了解realloc以及如何使用它。

答案 3 :(得分:0)

C中的动态通用数组非常容易。

追加/插入元素:

size_t size = 0, count = 0;
mytype_t *items; // array of mytype_t

mytype_t foo1, foo2, foo3;

carray_grow(items, size, count += 1); // grow to 1
items[0] = foo3;

carray_grow(items, size, count += 2); // grow to 3
carray_insert(items, count, 0, 2); // shift 2 up at 0
items[0] = foo1;
items[1] = foo2;

删除元素:

carray_remove(items, count, 0, 2); // remove 2 at 0
carray_grow(items, size, count -= 2); // shrink to 1

完全释放它?

carray_grow(items, size, count = 0);

后端(很少定义和单个函数):

int carray_xgrow(void **datap, size_t *sizep, size_t esize, size_t count);
// 0 or -1/errno(realloc)

#define carray_grow(array, size, count) carray_xgrow((void **)&(array), &(size), sizeof((array)[0]), count)
// 0 or -1/errno(realloc)

#define carray_move(array, from, to, n) memmove(&(array)[to], &(array)[from], sizeof((array)[0]) * (n))
#define carray_insert(array, count, i, n) carray_move(array, i, (i)+(n), (count)-(i)-(n))
#define carray_remove(array, count, i, n) carray_move(array, (i)+(n), i, (count)-(i)-(n))

int
carray_xgrow(void **datap, size_t *sizep, size_t esize, size_t count)
{
    assert(datap != NULL);
    assert(sizep != NULL);
    assert(esize > 0);

    size_t size = *sizep;
    {
        size_t cap = size / esize;

        if (cap >= count * 2) // regrow at 1/2
            cap = 0;

        while (cap < count) // grow by 3/2
            cap = (cap < 2) ? (cap + 1) : (cap * 3 / 2);

        size = cap * esize;
    }

    if (size != *sizep) {
        if (size) {
            void *data = realloc(*datap, size);
            if (data == NULL) return -1;
            *datap = data;
            *sizep = size;
        }
        else {
            free(*datap);
            *datap = NULL;
            *sizep = 0;
        }
    }
    return 0;
}

(注意大小以字节为单位,但是元素中的上限和计数。)

编辑:删除了少量依赖项