我的程序在主函数中声明了 3 个 int 数组(指针)。用户输入数组A
的长度,然后用随机数填充该数组。
然后,调用一个函数,该函数将所有 3 个数组作为其参数。它从数组A
中取出所有偶数并将它们放入数组B
中,并将所有奇数放入C
中。 B
和 C
的大小需要与其元素的数量相同。然后打印 B
的元素。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int velA, velB, velC; //the sizes of all the arrays
void napravi(int a[], int *b, int *c);
void main() {
int *a, *b, *c;
int i;
srand(time(NULL));
printf("Enter array lenght:");
scanf("%d", &velA);
getchar();
a = (int*)calloc(velA, sizeof(int));
b = (int*)malloc(4); //I have to initialize the variable in order to pass it as an argument ?
c = (int*)malloc(4);
for(i = 0; i < velA; i++) {
a[i] = rand() %101;
}
napravi(a, b, c);
for(i = 0; i < velB; i++) {
printf("%d ", b[i]);
}
free(a);
// free(b); //Windows has triggered a breakpoint in .exe
// free(c);
getchar();
}
void napravi(int a[], int *b, int *c) {
int i;
int j = 0, k = 0;
for(i = 0; i < velA; i++) {
if(a[i] % 2 == 0) {
j++;
}
else {
k++;
}
}
free(b);
free(c);
b = (int*)calloc(j, sizeof(int));
c = (int*)calloc(k, sizeof(int));
j = 0; k = 0;
for(i = 0; i < velA; i++) {
if(a[i] % 2 == 0) {
b[j] = a[i];
// printf("\n%d | %d", a[i], b[j]);
j++;
}
else {
c[k] = a[i];
k++;
}
}
velB = j;
velC = k;
}
此代码有 2 个问题。
- 首先,如果用户输入的值大于大约 420 左右的值,它就会开始打印垃圾值,例如 -17987777...
- 其次,当我最后尝试 free(b) 和 free(c) 时,程序崩溃并出现错误“Windows 在 my.exe 中触发了断点”。
最佳答案
在C
中,函数参数是按值传递的。因此,从 napravi()
函数中,您无法更改 b
本身。但是,您当然可以更改b
指向的地址处的值,即*b
。
如果您需要从 napravi()
更改 b
,您需要从 main()< 传递一个指向
.b
的指针
if the user enters a value that is bigger than something around ~420, it starts to print junk values like -17987777...
您面对的是undefined behaviour在您的代码中。
for(i = 0; i < velB; i++) {
printf("%d ", b[i]);
}
在上面的代码中,velB
值已正确更新(如代码预期),但 b
未正确更新(如预期来自 napravi()
函数)。因此,您超出了分配的内存区域,从而创建了 UB。
when I attempt to free(b) and free(c) at the end, the program crashes with an error "Windows has triggered a breakpoint in my.exe".
UB结果。
<小时/>注意:请do not cast C
中 malloc()
及其族的返回值。
关于C 动态内存分配数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30188051/