使用 realloc 缩小数组,丢失第一个元素
Making an array smaller with realloc, losing first element
我一直在尝试使用 calloc 和 realloc 制作一个示例程序,我遇到了一个问题,当我缩小一个整数数组时,它似乎删除了第一个元素而不是最后一个元素.
int *m = (int*)calloc(2, sizeof(int));
*m = 1;
*(m+1) = 2;
printf("\tInt 1: %d\n", m[0]);
printf("\tInt 2: %d\n\n", *(m+1));
// REALLOC
printf("How many elements the array have? ");
scanf("%d", &num);
*m = (int *)realloc(m, num * sizeof(int));
printf("ARRAY NOW HAS %d PLACES\n\n\t", num);
for(i = 0; i < num; i++) {
m[i] = i + 1;
printf("%d ", m[i]);
}
// DELETING MEMBERS OF AN ARRAY
while((d < 0) || (d > num)) {
printf("\n\nChoose which position of the previous array should be deleted (0 = first): ");
scanf("%d", &d);
}
printf("\nUPDATED ARRAY:\n\n");
for(i = d; i < num - 1; i++) {
m[i] = m[i + 1];
}
*m = (int *)realloc(m, (num - 1)*sizeof(int));
num--;
for(i = 0; i < num; i++) {
printf("%d ", m[i]);
}
程序输出示例为:
Int 1: 1
Int 2: 2
How many elements the array have? 17
ARRAY NOW HAS 17 PLACES
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Choose which position of the previous array should be deleted (0 = first): 6
UPDATED ARRAY:
10620272 2 3 4 5 6 8 9 10 11 12 13 14 15 16 17
如果我包括数组中本应删除的最后一个成员(在本例中为 m[16]),它会显示:
10620272 2 3 4 5 6 8 9 10 11 12 13 14 15 16 17 17
当然,我不完全确定发生了什么,但它似乎只是删除了 m[0] 的值?
在此先感谢您的帮助!
初始值被修改的原因是您正在分配它:
*m = (int *)realloc(m, num * sizeof(int));
应该是
m = realloc(m, num * sizeof(int));
您的代码还应产生警告,告诉您指向包含 int
s 的数组元素的指针赋值无效。修复此警告应该可以解决您的问题。
请注意,形式的赋值
m = realloc(m, ...);
在realloc
两边使用m
本质上是不安全的,因为realloc
可能returnNULL
——例如,当有没有足够的内存来分配。盲目分配给 m
会使 m
的旧值无法访问,从而阻止正确的释放。在生产中,你应该将 realloc
的结果分配给一个临时的,然后检查它是否为 NULL
,然后才将结果分配回 m
.
除了 好的答案外,当减少分配大小和重新分配失败(罕见事件)时,代码可以简单地继续使用原始指针。
建议重写,假设 num > 0
:
// *m = (int *)realloc(m, num * sizeof(int));
void *t = realloc(m, sizeof *m * num);
if (t) {
m = t;
}
我一直在尝试使用 calloc 和 realloc 制作一个示例程序,我遇到了一个问题,当我缩小一个整数数组时,它似乎删除了第一个元素而不是最后一个元素.
int *m = (int*)calloc(2, sizeof(int));
*m = 1;
*(m+1) = 2;
printf("\tInt 1: %d\n", m[0]);
printf("\tInt 2: %d\n\n", *(m+1));
// REALLOC
printf("How many elements the array have? ");
scanf("%d", &num);
*m = (int *)realloc(m, num * sizeof(int));
printf("ARRAY NOW HAS %d PLACES\n\n\t", num);
for(i = 0; i < num; i++) {
m[i] = i + 1;
printf("%d ", m[i]);
}
// DELETING MEMBERS OF AN ARRAY
while((d < 0) || (d > num)) {
printf("\n\nChoose which position of the previous array should be deleted (0 = first): ");
scanf("%d", &d);
}
printf("\nUPDATED ARRAY:\n\n");
for(i = d; i < num - 1; i++) {
m[i] = m[i + 1];
}
*m = (int *)realloc(m, (num - 1)*sizeof(int));
num--;
for(i = 0; i < num; i++) {
printf("%d ", m[i]);
}
程序输出示例为:
Int 1: 1
Int 2: 2
How many elements the array have? 17
ARRAY NOW HAS 17 PLACES
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Choose which position of the previous array should be deleted (0 = first): 6
UPDATED ARRAY:
10620272 2 3 4 5 6 8 9 10 11 12 13 14 15 16 17
如果我包括数组中本应删除的最后一个成员(在本例中为 m[16]),它会显示:
10620272 2 3 4 5 6 8 9 10 11 12 13 14 15 16 17 17
当然,我不完全确定发生了什么,但它似乎只是删除了 m[0] 的值?
在此先感谢您的帮助!
初始值被修改的原因是您正在分配它:
*m = (int *)realloc(m, num * sizeof(int));
应该是
m = realloc(m, num * sizeof(int));
您的代码还应产生警告,告诉您指向包含 int
s 的数组元素的指针赋值无效。修复此警告应该可以解决您的问题。
请注意,形式的赋值
m = realloc(m, ...);
在realloc
两边使用m
本质上是不安全的,因为realloc
可能returnNULL
——例如,当有没有足够的内存来分配。盲目分配给 m
会使 m
的旧值无法访问,从而阻止正确的释放。在生产中,你应该将 realloc
的结果分配给一个临时的,然后检查它是否为 NULL
,然后才将结果分配回 m
.
除了
建议重写,假设 num > 0
:
// *m = (int *)realloc(m, num * sizeof(int));
void *t = realloc(m, sizeof *m * num);
if (t) {
m = t;
}