一、为什么要动态存储
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
必须是由 malloc
、calloc
或 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;
}