NDK开发--C语言(动态静态开辟内存)

了解了C语言中一些基础知识后,我们今天来了解一下C语言的内存开辟(动态开辟、静态开辟)。

静态开辟:

C语言是面向过程的语言,所以在每一个函数执行时,都会进栈,执行完后弹栈,这一点有点类似于我们在面向对象语言中的对象的作用域的概念。

int main(){
    int i=0;
    int *p=&i;
    int arr[5];
    //.....变量,指针,数组,结构体等,
    return 0;
}

上述代码中定义的变量,都会在main函数执行完后,执行弹栈操作,释放栈区开辟的内存空间。

特别强调:

1)如果main函数调用了其他函数,其他函数同样需要完成进栈弹栈的操作,在栈区开辟的栈成员空间会被释放掉;

2)栈区可允许开辟的空间大小有限(大概2M,与平台有关);

3)静态开辟的内存大小是不能修改的;(尽量使用静态开辟,如果确实需要动态变化,再使用堆区)

动态开辟:

野指针:没有指向任何地址的指针,就是野指针,例如未给指针赋值;

悬空指针:指针指向的内存地址被释放掉,没有指向NULL的指针就是悬空指针

1)使用 malloc 在堆区开辟的内存空间

int main(){
    
    int * p;//野指针
   
    int * arr = malloc(1 * 1024 * 1024); // 堆区开辟 4M
    printf("dynamicAction函数,arr自己的内存地址:%p,堆区开辟的内存地址:%p\n", &arr, arr);

    //*****  堆区开辟的空间一定要free ,并将指针指向NULL
    free(arr); // 释放掉
    arr = NULL; // 重新指向一块内存地址00000,不赋值就是悬空指针了
    
    printf("悬空指针的地址:%p\n", arr); // 
    return 0;
}

动态开辟使用场景(根据用户需求来开辟):

int main(){
     int num;
    printf("请输入数的个数:");
      // 获取用户输入的值
    scanf("%d", &num);
    
     // 动态开辟 用户输入的值 空间的大小   【堆区】
    int * arr = malloc(sizeof(int) * num);
    
     int print_num;
    // 循环接收
    for (int i = 0; i < num; ++i) {
        printf("请输入第%d个的值:", i);

        // 获取用户输入的值
        scanf("%d", &print_num);

        arr[i] = print_num;
        printf("每个元素的值:%d, 每个元素的地址:%p\n", *(arr + i), arr + i);
    }
    return 0;
}

2) realloc 动态开辟之使用

说明:

1)realloc 是在源堆空间地址上追加开辟的意思;

2)返回的指针与第一个参数指针指向的是同一个地址;第一个参数是源空间地址,第二个参数是需要开辟的总大小

3)动态开辟的地址,都需要free,并指向NULL,但是重复free会crash, 所以在free之前要做判断

int main(){
    
  int num;
    printf("请输入动态开辟的的个数:");
    // 获取用户输入的值
    scanf("%d", &num);

    // 动态开辟 用户输入的值 空间的大小   【堆区】
    int *arr = malloc(sizeof(int) * num);
    printf("malloc函数返回的指针地址:%p", arr);
    //给元素赋值
    for (int i = 0; i < num; i++) {
        *(arr + i) = i + 100;
    }
    printf("**********打印动态开辟的元素信息*************\n");
    for (int i = 0; i < num; i++) {
        printf("第  %d  个元素的值:%d,  地址:%p\n", i, arr[i], arr + i);
    }


    int new_num;
    printf("请输入重新动态开辟的的个数:\n");
    // 获取用户输入的值
    scanf("%d", &new_num);
    int *new_arr = realloc(arr, sizeof(int) * (num + new_num));
    printf("realloc函数返回的指针地址:%p", new_arr);
    if (new_arr) {
        for (int i = num; i < num + new_num; i++) {
            *(new_arr + i) = 200 + i;
        }

        printf("**********重新开辟的元素信息*************\n");
        for (int i = 0; i < num + new_num; i++) {
            printf("第  %d  个元素的值:%d,  地址:%p\n", i, new_arr[i], new_arr + i);
        }
    }

    if (new_arr) {
        free(new_arr);
        new_arr = NULL;
    }

    if (arr) {
        free(arr);
        arr = NULL;
    }
}


//输出结果
/**
请输入动态开辟的的个数:3
malloc函数返回的指针地址:0000000000AD6CD0
**********打印动态开辟的元素信息*************
第  0  个元素的值:100,  地址:0000000000AD6CD0
第  1  个元素的值:101,  地址:0000000000AD6CD4
第  2  个元素的值:102,  地址:0000000000AD6CD8
请输入重新动态开辟的的个数:
3
realloc函数返回的指针地址:0000000000AD6CD0
**********重新开辟的元素信息*************
第  0  个元素的值:100,  地址:0000000000AD6CD0
第  1  个元素的值:101,  地址:0000000000AD6CD4
第  2  个元素的值:102,  地址:0000000000AD6CD8
第  3  个元素的值:203,  地址:0000000000AD6CDC
第  4  个元素的值:204,  地址:0000000000AD6CE0
第  5  个元素的值:205,  地址:0000000000AD6CE4
*/

下节预告:C语言--结构体及结构体指针

你可能感兴趣的:(NDK开发--C语言(动态静态开辟内存))