动态内存分配
一、存储区划分
从低到高(内存地址小----内存地址大) : 代码区---常量区---静态区---堆区---栈区
栈内存
//凡是在函数体内定义的变量 都存储在栈区(包括形参)。 int a = 10;//a也是在栈区域里面 float b = 1.5;//b也是在栈区域里面 char c = ‘b‘; double d = 3.14; printf("%p %p %p %p\n",&a,&b,&c,&d); //栈的特点先进后出,先定义的变量先入栈,后定义的变量后入栈。 //调用函数时。函数中得变量会陆续入栈,函数调用结束时,变量陆续出栈 //栈区内存的分配与回收,有系统自动进行。
常量区
‘a’字符常量 5整型常量 “iphone” 字符串常量
常量占用内存 只读状态 不能修改
静态存储区
static int a = 5;
1.只初始化一次 2.如果初始没给值,默认为0 3.只有程序退出才释放(永远存在)
将变量定义的类型前加static 则该变量存储在静态存储区
//编译期就已经进入内存,程序运行期间h一直存在,不会被销毁 ,程序结束时h才会被销毁,如果没有给h赋值,h默认初始值为0 static int h = 10;
#import <Foundation/Foundation.h> int m = 100; //定义在函数外面的变量称为全局变量,全局变量跟静态变量一样,存储在全局区(也叫静态区) int main(int argc, const char * argv[]) {
二、堆内存分配函数
堆内存 一般由程序员分配和释放
malloc: void *malloc(unsigned int size);//void * 表示任意类型的指针
int * p = (int *)malloc(sizeof(int) * n);//(int *)强转类型 sizeof(int)分配的内存大小 *n元素个数
char *str = malloc(8);
//malloc主要功能是从 堆区 开辟 指定大小 得内存空间 //内存大小以 字节 为单位 //返回值是这段空间的首位置 //我们需要定义一个指针保存返回值 int *p = malloc(4); //p在栈区。malloc操作的十堆区,p存的地址是堆区地址 int a = 10; int *q = &a; //a在栈区,q也在栈区,q存的a的地址,也就是栈区地址
strcpy(str, ”iPhone”);
free(str);//标记删除,不清除内容
struct student{ char name[20]; int age; int num; char sex; }; typedef struct student Student; Student *pstu = malloc(sizeof(Student)*5); pstu->age = 20; free(pstu);//释放内存,160个字节归还给系统
Student *p = malloc(sizeof(Student));//分配的内存大小要用 sizeof(Student)
void * calloc(unsigned n,unsigned size);//n内存个数 size大小 calloc 清空内存
//分配n个size大小的空间,并且把该内存上的所有字节清零
void *realloc(void *p,unsigned newSize);//按新的长度重新分配
void *memset(void *s , int c , size_t n);//memset(p , 0 , sizeof(int) * 5) 通常用于清除结构体或者数组数据
//输入三个学员的姓名,动态分配内存保存学院姓名,并最后输出 //定义一个包含3个字符指针的数组,他们默认指向null(0) char *names[3]={0}; //定义一个临时数组,用于存放输入的单个单词 char temp[50] = {0}; for (int i = 0; i<3; i++) { scanf("%s",temp);//temp前面不要加&,因为数组名本身就是地址 //获取单个单词的长度 unsigned long length = strlen(temp); //让指针指向开辟的堆空间 names[i] = malloc(length+1); //将输入的内容拷贝到堆空间里 strcpy(names[i], temp); } for (int i = 0; i<3; i++) { printf("%lu %s\n",strlen(names[i]),names[i]); free(names[i]);
}
void *memcpy(void *dest,const void *source,size_t n)