我在围绕正确使用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;
}
我的方法是创建具有增加的内存分配的临时指针,然后将现有日期复制到它并将数据指针指向新位置。我怀疑我可能会以完全错误的方式看待这个问题。
任何帮助提示或指示(双关语)都将不胜感激。提前谢谢。
答案 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;
}
(注意大小以字节为单位,但是元素中的上限和计数。)
编辑:删除了少量依赖项