繁体   English   中英

C动态内存分配数组

[英]C dynamic memory allocation array

我的程序在主函数中声明了3个int数组(指针)。 用户输入数组A的长度,然后用随机数填充。

然后,调用一个函数,该函数将所有3个数组作为其参数。 它从数组A取出所有偶数,并将它们放入数组B ,并将所有奇数放入C BC的大小必须与它们的元素数相同。 然后打印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指向的adrress ,即*b

如果需要从napravi()更改bnapravi()需要从main()传递指向b的指针。

如果用户输入的值大于〜420附近的值,它将开始打印-17987777之类的垃圾值...

您在代码中面临未定义的行为

for(i = 0; i < velB; i++) {
        printf("%d  ", b[i]);
    }

在上面的代码中, velB值已正确更新( 如代码所期望 ),但b没有被更新( napravi()函数所期望的 )。 因此,您将超出分配的内存区域,从而创建UB。

当我尝试在最后释放free(b)和free(c)时,程序崩溃,并显示错误“ Windows在my.exe中触发了断点”。

UB的结果。


注意:请不要Cmalloc()和family的返回值。

尝试这个

int main(void) {
    int *a, *b, *c;
    int i;
    srand(time(NULL));

    printf("Enter array lenght:"); 
    scanf("%d", &velA);
    getchar();

    a = (int*)calloc(velA, sizeof(int));
    //b = NULL;//There is no need to set the value
    //c = NULL;//NULL is better than 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);
    free(c);
    getchar();
    return 0;
}

void napravi(int a[], int **b, int **c) {
    int i;
    int j = 0, k = 0;

    *b = *c = NULL;
    velB = velC = 0;
    if(a == NULL || velA == 0)
        return;

    for(i = 0; i < velA; i++) {
        if(a[i] % 2 == 0) {
            j++;
        }
    }

    if(velB = j)
        *b = (int*)malloc(velB * sizeof(int));
    if(velC = velA - velB)
        *c = (int*)malloc(velC * sizeof(int));


    j = 0; k = 0;

    for(i = 0; i < velA; i++) {
        if(a[i] % 2 == 0)
            (*b)[j++] = a[i];
        else
            (*c)[k++] = a[i];
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM