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
",a,b);
//    printf("%p,%p ",&a,&b);
//}
//
//void test2(){
//
//    int c,d;
//    printf("c=%d,d=%d
",c,d);
//    printf("%p,%p ",&c,&d);
//
//
//}



    



int main(int argc, const char * argv[]) {
   
//    test1(4,5);
//    
//    test2();
//    
    //从大到小
    
    
    //栈区
    
//    int a=5;
//    printf("栈区=%p
",&a);
//    
//    
//    
//    //堆区
//    NSObject *abj=[NSObject new];
////    NSString *string =[NSString alloc init];
//    printf("堆区:%p
",abj);
//    
//    
//    
//    //静态区
//    static int b=6;
//    printf("静态区:%p
",&b);
//    
//    
//    
//    //常量区
//    char *p="iphone";
//    printf("常量区 :%p
",p);
//    //代码区
//    
//    printf("代码区:%p
",&test);
//    
    
    
    
//    //const 可以把我们的变量改为常量
//    
//   const int c=6;
//    c=9; //这样写是错误的,因为这里的c被const修饰之后成为一个常量,不可以被改变
    
#pragma mark----栈区---
    /*
     
     分配规则:有系统自行分配,由高到低,
     
     存储方式: 由低到高
     栈区: 一般存储的是我们定义的一些变量是先进后出,后进先出
     ()
     
     */
    
//    int *p=NULL;//首先我们定义的指针 一定是在栈区,因为这里定义的是一个 int * 类型的指针变量
//    printf("p=%p
",p);
//    
//    
//    char *p1="iphone";//我们这里的p1是指向的是常量区的字符串,因为我们栈区的指针指向了常量区的字符串"iphone:,而常量区的 'iphone'把地址给了指针p1所以现在p1存储的是我们常量去的地址
//    printf("p1=%p
",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
",arr);
//    
//    strcpy(arr, "Android");
//    printf("%s
",arr);
//    
//    strcpy(arr, "I want you");//不推荐 这样去写,因为后边的几个字节的空间不知道是占用了谁的空间
//    printf("%s
",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]!='') {
//        //进行判断
//        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
",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
",p);
//    free(p);
//    p=NULL;
//    
//    char *str=NULL;//栈区
//    
//    str=calloc(10, sizeof(char));
//    //开辟空间并进行清零的操作
//    strcpy(str, "iphone");
//    printf("%s
",str);
//    
    
//    int *p_old=malloc(8);
//    int *p_new=realloc(p_old,20);
//    printf("p_old=%p p_new=%p
",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("
");
//    
//    memset(array, 0, 12);//首先我们int类型占4个字节,然而我们这里是初始化了12 个字节,所以我们控制台会有3个整型被初始化.
//    for (int i=0; i<12; i++) {
//        printf("%d ",array[i]);
//    }printf("
");
//    
//    
//    
//    char *ch=malloc(10);//申请10个字节大小的空间
//    memset(ch, 'b', 10);//
//    for (int i=0; i<10; i++) {
//        printf("%c ",ch[i]);
//    }printf("
");
//    
//    
    //两种遍历方式:
    //while(){}
    //for 循环
    //for in oc当中快速枚举
    
    
    //内存拷贝
//    
//    char name[]= "supermen";
//    char num[]= "007";
//    memcpy(name+2 , num, 3);
//    printf("%s
",name);
    
    
    //内存比较
    //
//    char name1[]="aeftsdfdsf";
//    char name2[]="abdesdvsdf";
//  int name=memcmp(name1, name2, 2);
//    printf("%d
",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("
");
//    for (int i=0; i<3; i++) {
//        
//        b[i]=arc4random()%(10-1+1)+1;
//        printf("%d ",b[i]);
//    }
//
//    printf("
");
//    
//    int c=memcmp(a, b, 12);
//    
//    if (c==0) {
//        printf("good!!");
//        
//    }else{
//        printf("faied!!");
//    }
//    
    
#pragma mark--静态区:全局变量 局部变量--
    
//    static  int a =8;
//    a=9;
//    
//    printf("%d
",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("
");
//        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("
");
//    
//    
//    
//    
//    //有一个已知的整形数组,赋值随机[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("
");
//    for (int i=0; i<count; i++) {
//        printf("%d ",*(d+i));
//    }
//    printf("
");
    
    
    //由一已知字符串,其中包含数字,字符,提取其中数字符,动态分配内存保存
////    
//    char arr[]="1h2g3g4h5g";
//    int i=0;
//    int count1=0;
//    while (arr[i]!='') {
//        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("
");
//    
//    //在堆区为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;
}
原文地址:https://www.cnblogs.com/huyibo/p/5475230.html