【发布时间】:2022-01-17 00:21:15
【问题描述】:
int *dynArr(int* arr, int n, int isEven) {
int count = 0;
int* t = (int*)calloc(n, sizeof(int));
assert(t);
if (isEven == 1) {
for (int i = 0; i < n; i++) {
if (arr[i] % 2 == 0) {
t[count++] = arr[i];
}
}
}
t = (int*)realloc(*t, count * sizeof(int));
return t;
}
void main() {
int a[] = { 1,8,3,6,11 };
int n = sizeof(a) / sizeof(int);
int isEven = 1;
int* arr = dynArr(a, n, isEven);
for (int i = 0; i < n; i++) {
printf("%d", arr[i]);
}
}
问题是当我返回数组时我没有得到任何输出,当我调试时我得到这个错误:“homelab8.exe 中 0x7A08B54D (ucrtbased.dll) 处的未处理异常:0xC0000005: 访问冲突读取位置 0x00000004。” 有人知道我该如何解决这个问题?
【问题讨论】:
-
启用编译器的警告! (我用
-Wall -Wextra -pedantic配合gcc和clang。)发现两个问题,一个大问题。 -
在
t = (int*)realloc(*t, count * sizeof(int));中,您传递的*t与t[0]相同。您应该传递一个指向已分配内存块的指针,即t。 -
如果代码是在定义
NDEBUG的情况下编译的,那么assert(t);会发生什么?教你使用assert()进行必要的错误检查的人是被误导的。 -
你访问元素
0..n-1,但是你使用realloc创建了一个只包含count元素的数组,数量比n小 -
在任何情况下
realloc可能会失败,但是您的代码会产生内存泄漏:t指向尚未存在的数组的旧值被NULL覆盖。从一开始就习惯于做正确的事:temporary = realloc(current); if(temporary) { current = temporary; } else { /* some appropriate error handling; if need be, still can use old value of current – even if you only free it */ }