我想调整一维整数数组的大小,保留原始数组中的值,并用零初始化新值。到目前为止,我已经提出了两种选择(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;
答案 0 :(得分:2)
首先,您需要传递要更新的指针的地址,否则将无法在函数外部修改指针。因为realloc如果找不到足够长的连续区域,可能会改变数据的位置。
第二,请确保您严格限制数组大小与字节大小。
// Resizes composition
int compo_resize(int len, int **a) {
printf("Note: resizing composition...\n");
// reallocate memory
void *c = realloc(*a, sizeof(int) * 2 * len);
if (c == NULL) {
fprintf(stderr, "realloc() failed");
return LieanderErrorOutOfMemory;
}
else {
// reassign pointer
*a = c;
// zero out new elements
memset(&c[len], 0, sizeof(int) * len);
}
return LieanderSuccess;
}
答案 1 :(得分:2)
int *a
参数需要替换为int **a
,因为您要代表调用者更改指针。
// Resizes composition
int compo_resize(int len, int **a) {
printf("Note: resizing composition...\n");
// reallocate memory
int *c = realloc(*a, sizeof(c[0])*2*len);
if (c == NULL) {
fprintf(stderr, "realloc() failed");
return LieanderErrorOutOfMemory;
}
else {
// reassign pointer
*a = c;
// zero out new elements
memset(&c[len], 0, len * sizeof c[len]);
}
return LieanderSuccess;
}
答案 2 :(得分:0)
1-不要释放所有带涂层的内存,因为在函数返回后将使用它。
2-将免费的旧* a复制到* c后,考虑使用。
3-从以下位置更改函数声明:
int compo_resize(int len, int *a);
到
int compo_resize(int len, int **a);
因为要更新指针本身的值以指向新创建的数组。