【发布时间】:2019-04-04 21:34:01
【问题描述】:
我想调整一维整数数组的大小,保留原始数组中的值并用零初始化新值。到目前为止,我已经提出了两种选择(a)使用calloc 和memcpy:
// Resizes composition
int compo_resize(int len, int *a) {
// initialise new composition
int *c = calloc(2*len, sizeof a[0]);
if (c == NULL) {
fprintf(stderr, "calloc() failed");
return LieanderErrorOutOfMemory;
}
// copy numbers from old to new composition
memcpy(c, a, sizeof a[0] * len);
// modify composition in-place
*a = *c;
// release memory
free(c);
return LieanderSuccess;
}
和 (b) 使用 realloc 和 memset:
// Resizes composition
int compo_resize(int len, int *a) {
printf("Note: resizing composition...\n");
// reallocate memory
void *c = realloc(a, 2*len);
if (c == NULL) {
fprintf(stderr, "realloc() failed");
return LieanderErrorOutOfMemory;
}
else {
// reassign pointer
a = c;
// zero out new elements
memset(&a[len], 0, len * sizeof a[len]);
}
return LieanderSuccess;
}
我想说第二种方法更优雅、更快。但是,当集成到更大的程序中时,代码开始返回意外的错误值。我在方法(b)中做错了吗?我错过了什么明显的东西吗?
对combo_resize() 的调用是int retval = compo_resize(f->len, f->a),其中f 是一个称为pair 的自定义结构:
typedef struct {
int fac; // multiplication factor
int idx; // index of Lieander
int len; // length of compositions
int kth; // no. of elements in compositions
int *a; // composition 1
int *b; // composition 2
int num; // natural no.
} pair;
【问题讨论】:
-
你能更具体地定义“意外的、不正确的值”吗?您在该函数中使用
void*表示临时int*也很奇怪。只需使用正确的类型即可避免歧义。听起来你在这里有很多未定义的行为是由于在free之后使用指针等等造成的。 -
第二个,
realloc(a, 2*len);是错误的。应该是realloc(a, 2 * len * sizeof *a);你记得memset中的sizeof乘数;您在分配中遗漏了它的任何特殊原因?无关,memset可以简单地使用a+len作为目标。而且我希望 调用者 以某种方式知道新容量是什么,因为没有从该函数返回给他们的相同功能。 -
您将立即释放新创建的阵列。而
*a = *c;的意图根本就不清楚。 -
@mabalenk 请edit 您的问题并在那里进行说明。还告诉我们
f->a到底是什么。但也许你应该使用下面的赞成答案之一并像这样调用函数:compo_resize(f->len, &f->a) -
mabalenk,为什么
2*在realloc(a, 2*len)?我希望有像compo_resize(int *a, int oldsize, int newsize)这样的签名。
标签: c memcpy realloc calloc memset