C 语言内存管理
//
// main.m
#import <Foundation/Foundation.h>
int a =100;
//void test(){
// int a =8;
//
//}
//当函数调用的时候test2当中的变量c d会打印test1中a,b的值,是因为当我们函数test1运行结束之后会释放a,b的标记(地址),但是a b的值依然存在,所以当我们类型相同的函数和其内部变量定义出来之后(没有初值),我们还会使用的是相同的内存里边的相同的值所以切记要去"赋初值";
//
//void test1(int a,int b){
//
//
// printf("a=%d,b=%d\n",a,b);
// printf("%p,%p ",&a,&b);
//}
//
//void test2(){
//
// int c,d;
// printf("c=%d,d=%d\n",c,d);
// printf("%p,%p ",&c,&d);
//
//
//}
int main(int argc, const char * argv[]) {
// test1(4,5);
//
// test2();
//
//从大到小
//栈区
// int a=5;
// printf("栈区=%p\n",&a);
//
//
//
// //堆区
// NSObject *abj=[NSObject new];
//// NSString *string =[NSString alloc init];
// printf("堆区:%p\n",abj);
//
//
//
// //静态区
// static int b=6;
// printf("静态区:%p\n",&b);
//
//
//
// //常量区
// char *p="iphone";
// printf("常量区 :%p\n",p);
// //代码区
//
// printf("代码区:%p\n",&test);
//
// //const 可以把我们的变量改为常量
//
// const int c=6;
// c=9; //这样写是错误的,因为这里的c被const修饰之后成为一个常量,不可以被改变
#pragma mark----栈区---
/*
分配规则:有系统自行分配,由高到低,
存储方式: 由低到高
栈区: 一般存储的是我们定义的一些变量是先进后出,后进先出
()
*/
// int *p=NULL;//首先我们定义的指针 一定是在栈区,因为这里定义的是一个 int * 类型的指针变量
// printf("p=%p\n",p);
//
//
// char *p1="iphone";//我们这里的p1是指向的是常量区的字符串,因为我们栈区的指针指向了常量区的字符串"iphone:,而常量区的 'iphone'把地址给了指针p1所以现在p1存储的是我们常量去的地址
// printf("p1=%p\n",p1);
//
#pragma mark --堆区--
/*
堆区:是唯一一个由我们高贵的程序员自行管理 开辟释放的空间
我们一般做一些操作主要是在堆区上进行,
例如,c语言当中的malloc oc语言中的new alloc等
*/
// int *a=malloc(4);//向系统申请了4个字节大小的空间
// int *b =malloc(sizeof(int)*4);//向系统申请了4个int 类型的大小的空间(也就是16个字节)
//
//堆内存分配函数:
//void *malloc(size_t);
//void *也叫空指针,可以返回任意类型
// char *arr=malloc(sizeof(char)*8);//向系统申请8个char类型的大小的空间
// strcpy(arr, "iphone");//将"iphone"拷贝到arr中
// printf("%s\n",arr);
//
// strcpy(arr, "Android");
// printf("%s\n",arr);
//
// strcpy(arr, "I want you");//不推荐 这样去写,因为后边的几个字节的空间不知道是占用了谁的空间
// printf("%s\n",arr);
// free(arr);
// arr=NULL;
// int *a=malloc(sizeof(int)*4);
// free(a);
// a=NULL;
//
//
//
// //申请8个short类型的大小的空间
//
// short *b=malloc(sizeof(short)*8);
// free(b);
// b=NULL;
// //free是标记释放,但是里面的值依然存在
//
//free(b);过度释放
// //定义一个由10个元素的数组
// int arr[10]={1,2,3,4,5,6,7,8,9,10};
// //开辟空间
// int *p = malloc(sizeof(int)*10);
// //将数组元素放入到我们开辟的空间中
// *p=arr[0];
// *(p+1)=arr[1];
// *(p+2)=arr[2];
// free(p);
// p=NULL;
//
// //定义一个结构体
// typedef struct student{
// char name[20];
// int age;
//
// }stu;
// //开辟一个结构体大小的空间
//
// stu *s=malloc(sizeof(stu));
//有一个字符串 其中包含数字,提取其中的数字,要求动态分配内存保存
//思路,先计算数字的个数,然后根据数字的个数进行开辟空间
// char arr[]="1a2b3c4d";
//
// int i=0;
// //定义一个变量来记录数字的个数
// int count=0;
//
// //定义一个字符串数组 接收我们的数字
// char str[100]={0};
//
// //然后遍历arr
// while (arr[i]!='\0') {
// //进行判断
// if (arr[i]>='0'&&arr[i]<='9') {
// str[count]=arr[i];
// count++;
//
// }
// i++;
// }
// //手动开辟空间
// char *p=malloc(sizeof(char)*count+1);
//
//
// //将我们的数字数组进行拷贝
// strcpy(p, str);
//
//
// printf("%s\n",p);
//
// free(p);
// p=NULL;
//输入三个单词,动态分配内存保存单词,并在最后输出
#pragma mark --其他内存分配函数--
//其他内存分配函数
/**
calloc
void *calloc(size_t(n),size_t(size));
calloc分配n个size大小的空间,并对其内容进行一个清0
的操作.calloc相比malloc来说效率会低一些
realloc
void *realloc(void *,size_t);
//根据给定的地址以及给定的大小从新分配,可以清0.但是会带来效率的耗损,
1,如果开辟空间比原来的空间小, 那么在原来空间的基础上进行开辟(开辟的空间要比原来空间小)
2.如果开辟的空间比原来空间大的话,那么他会自动开辟一块空间
不需要我们自己手动释放空间 系统会自动释放
**/
//在堆区开辟10个存储空间
// //malloc
// char *p=malloc(sizeof(char)*10);
// strcpy(p,"bobo");
// printf("%s\n",p);
// free(p);
// p=NULL;
//
// char *str=NULL;//栈区
//
// str=calloc(10, sizeof(char));
// //开辟空间并进行清零的操作
// strcpy(str, "iphone");
// printf("%s\n",str);
//
// int *p_old=malloc(8);
// int *p_new=realloc(p_old,20);
// printf("p_old=%p p_new=%p\n",p_old,p_new);
//
// free(p_old);
// p_old=NULL;
//free(p_new);//系统会自动释放,这里的释放属于过度释放
#pragma mark --内存操作函数--
/***内存操作函数
初始化内存
从给定的地址开始初始化n个字节,初始化的内容为c
memset(void*s,int c,size_t n);
内存拷贝
/从source指向的内存开始拷贝到dest,拷贝n个字节
memcpy(void *dest, void source, size_t n);
内存比较
比较buf1和buf2,比较n个字节
memcmp(const void *buf1, const void *buf2, size_t n);
**/
//初始化内存
// int *array=malloc(12);
// for (int i=0; i<12; i++) {
// array[i]=arc4random()%(10-1+1)+1;
// printf("%d ",array[i]);
// }printf("\n");
//
// memset(array, 0, 12);//首先我们int类型占4个字节,然而我们这里是初始化了12 个字节,所以我们控制台会有3个整型被初始化.
// for (int i=0; i<12; i++) {
// printf("%d ",array[i]);
// }printf("\n");
//
//
//
// char *ch=malloc(10);//申请10个字节大小的空间
// memset(ch, 'b', 10);//
// for (int i=0; i<10; i++) {
// printf("%c ",ch[i]);
// }printf("\n");
//
//
//两种遍历方式:
//while(){}
//for 循环
//for in oc当中快速枚举
//内存拷贝
//
// char name[]= "supermen";
// char num[]= "007";
// memcpy(name+2 , num, 3);
// printf("%s\n",name);
//内存比较
//
// char name1[]="aeftsdfdsf";
// char name2[]="abdesdvsdf";
// int name=memcmp(name1, name2, 2);
// printf("%d\n",name);
//定义两个整型指针,分别用malloc calloc对其分配空间3个元素,malloc分配空间用calloc进行清零操作,随机对数组 进行赋值,,随机范围1-3;使用memcmp比较两个数组,如果相同打印good!不同打印faied...
//
// int *a=malloc(12);
// int *b=calloc(3,4);
//
// memset(a, 0, 12);
//
// for (int i=0; i<3; i++) {
//
// a[i]=arc4random()%(10-1+1)+1;
// printf("%d ",a[i]);
//
// }printf("\n");
// for (int i=0; i<3; i++) {
//
// b[i]=arc4random()%(10-1+1)+1;
// printf("%d ",b[i]);
// }
//
// printf("\n");
//
// int c=memcmp(a, b, 12);
//
// if (c==0) {
// printf("good!!");
//
// }else{
// printf("faied!!");
// }
//
#pragma mark--静态区:全局变量 局部变量--
// static int a =8;
// a=9;
//
// printf("%d\n",a);
//
//
/*
静态去:一般存储的是我们的一些全局和局部的变量
static修饰:在程序运行的周期当中值初始化一次
静态区内的东西 直到程序运行结束 才会被释放,在这个当中它伴你久久;
1.只初始化一次
2.如果没有初始化,默认为0;
3.只有程序退出才释放
*/
#pragma mark--常量区--
/*
常量区,一般存储的是字符串,数字,字符串等常量,这里边的东西都是readonly(只读),我们只是可以看但是不可以修改,一旦修改程序混崩溃
*/
// char *p="iphone";
//// *(p+1)='w';
// printf("%c",*(p+1));不可以去修改.
#pragma mark--代码区--
//函数存储在哪个区?
/*
我们编写的程序,运行程序之后,最终都会转换成二进制的形式存储在代码区中
**/
//练习:在堆区开辟空间,存储10个整数
// int *a=malloc(sizeof(int)*10);
// a=NULL;
//
// //在堆区开辟空间,存储5个短整型数,为每个元素随机赋值[20,30],并对数组进行升序排序
// short *b=malloc(5);
// for (int i=0; i<5; i++) {
// b[i]=arc4random()%(30-20+1)+20;
// printf("%d ",b[i]);
// }printf("\n");
// for (int i=0; i<4; i++) {
// for (int j =0; j<4-i; j++) {
// if (b[j]>b[j+1]) {
// short temp=b[j];
// b[j]=b[j+1];
// b[j+1]=temp;
// }
// }
// }for (int i=0; i<5; i++) {
// printf("%d ",b[i]);
// }printf("\n");
//
//
//
//
// //有一个已知的整形数组,赋值随机[20,40]将大于30的数字存储到堆区空间上,在堆区动态开辟空间
//
// int c[10]={0};
// int count=0;
// for (int i=0; i<10; i++) {
// c[i]=arc4random()%(40-20+1)+20;
// printf("%d ",c[i]);
// if (c[i]>30) {
// count++;
// }
// }
// int *d=malloc(sizeof(int)*count);
//
// for (int i=0,j=0; i<10; i++) {
// if (c[i]>30) {
// *(d+j)=c[i];
// j++;
// }
// }
// printf("\n");
// for (int i=0; i<count; i++) {
// printf("%d ",*(d+i));
// }
// printf("\n");
//由一已知字符串,其中包含数字,字符,提取其中数字符,动态分配内存保存
////
// char arr[]="1h2g3g4h5g";
// int i=0;
// int count1=0;
// while (arr[i]!='\0') {
// if (arr[i]>='0'&&arr[i]<='9') {
// count1++;
// }
// i++;
//
// }
//
// char *p1=malloc(sizeof(char)*count1+1);
// for (int i=0,j=0; i<9; i++) {
// if (arr[i]>='0'&&arr[i]<='9') {
// *(p1+j)=arr[i];
// j++;
// }
// }for (int i=0; i<count1; i++) {
// printf("%c",*(p1+i));
// }printf("\n");
//
// //在堆区为3个整数开辟空间,存储10,20,30;
//
// int *q=malloc(sizeof(int)*3);
// for (int i=0; i<3; i++) {
// *q=(i+1)*10;
//
// printf("%d ",*q);
// }
//
//
//
// int array[3] = {1,4};
// for(int i = 0;i < 3;i++)
// { printf("%d",array[i]); }
// int x=10,y=10,i;
// for(i=0;x>8;y=++i){
// printf("%d %d ",x--,y);
//}
return 0;
}