C语言核心篇 第三期:动态存储(malloc)

一、为什么要动态存储

1.原因

        栈区(1M)内存很小,存放过多导致程序崩溃。

2.内存(内部存储器)
1)特点

        程序启动后占用内存,断电即消失

2)x86系统(x86硬件)

        win32位操作系统 (windows32位操作系统)

                地址总线根数32根

                2^32B 4G内存

        寻址能力 地址总线位数

                假设一根线的信号 0 1

                寻址能力为2个编号的地址 2B内存

                32位系统的寻址能力为2^32,即4GB内存空间

        指针大小

                x86(win32) 4B

                x64(win64) 8B

                        存在虚拟内存,暂时不研究

3)内存划分        

128M非法访问区

        0x0000 0000B~0x0800 0000B

        #define NULL 0;

        int*p =NULL;        //error

        p指针指向了0号地址空间(非法访问区)

        空指针不能解引用

代码区.text

数据区.data

        静态局部 静态全局 普通全局 字符串常量

堆区.heap

        占用大量内存 1.5-1.9G

        动态内存管理

                malloc calloc realloc free

                由低地址向高地址开辟

                程序员自己申请 自己释放

栈区.stack

        占少量内存 1M

        函数内普通局部变量

        由高地址向低地址开辟

内核使用

        Windows: 2:2 用户使用2G 内核使用2G

        Linux: 3:1 用户使用3G 内核使用1G

二、动态存储分配函数 #include<stdlib.h>

1.malloc 分配内存

        malloc函数用于动态分配指定字节数的内存,返回指向该内存的指针。分配的内存未初始化,内容随机。

int *ptr = (int*)malloc(10 * sizeof(int));    //分配10个整型空间
if (ptr == NULL) {    // 处理分配失败
    exit(EXIT_FAILURE);
}
free(ptr);            // 使用完释放 防止野指针
ptr=NULL;
原型:void* malloc(size_t size);

        参数:size 是需要分配的字节数。

        返回值:成功时返回指向分配内存的指针,失败时返回 NULL

2.calloc 分配并初始化内存

        calloc函数分配内存并将其初始化为零。参数为元素数量和每个元素的大小。

int *ptr = (int*)calloc(10, sizeof(int));    //分配并清零10个整型空间
if (ptr == NULL) {
    // 处理分配失败
}
原型:void* calloc(size_t num, size_t size);

        参数:num元素数量, size每个元素的字节数。

        返回值:与 malloc 相同。

3.realloc 调整内存大小

realloc函数用于调整已分配内存的大小,可扩大或缩小。原有数据保留,新空间未初始化。        

扩容的三种情况:

        原有内存后续有足够空间:直接扩展

        原有内存后续空间不足,但堆中有足够空间:重新分配并拷贝数据

        堆中无足够空间:返回NULL

int *new_ptr = (int*)realloc(ptr, 20 * sizeof(int));  // 扩容到20个整型
if (new_ptr == NULL) {
    // 处理分配失败
    free(ptr);              // 释放原内存
    exit(EXIT_FAILURE);
}
ptr = new_ptr;              // 更新指针
原型:void* realloc(void* ptr, size_t new_size);

        参数:ptr原内存指针, new_size新的字节数。

        返回值:成功时返回新指针(可能与原指针不同),失败时返回 NULL(原内存仍有效)。

4.free释放动态内存

        free 释放动态内存 必须配对使用malloc/calloc/realloc和free,避免内存泄漏。

原型:void free(void* ptr);

        参数:ptr 必须是由 malloccalloc 或 realloc 返回的指针。

三、动态数组示例

        编写一个程序,动态创建一个二维数组,并允许用户输入数组的行数和列数。然后,让用户输入数组的元素,并输出该二维数组。

#include <stdio.h>
#include <stdlib.h>

int main() {
    int rows, cols;  
                  
    // 输入行数和列数
    printf("请输入二维数组的行数: ");
    scanf("%d", &rows);
    printf("请输入二维数组的列数: ");
    scanf("%d", &cols);

    // 动态分配二维数组的内存
    int **matrix = (int **)malloc(rows * sizeof(int *));
    if (matrix == NULL) {
        printf("内存分配失败!\n");
        return 1;
    }
    for (int i = 0; i < rows; i++) {
        matrix[i] = (int *)malloc(cols * sizeof(int));
        if (matrix[i] == NULL) {
            printf("内存分配失败!\n");
            return 1;
        }
    }

    // 输入二维数组的元素
    printf("请输入二维数组的元素:\n");
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            scanf("%d", &matrix[i][j]);
        }
    }

    // 输出二维数组
    printf("二维数组的元素为:\n");
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }

    // 释放二维数组的内存
    for (int i = 0; i < rows; i++) {
        free(matrix[i]);
    }
    free(matrix);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值