• 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;
    }
  • 相关阅读:
    【SpringBoot】 理解SpringBoot的启动原理
    【SpringBoot】SpringBoot的基础,全面理解bean的生命周期
    【转】 Linux 命令解释(Linux基础二)
    【转】 Linux 的目录详解 (Linux基础一)
    【SpringBoot】 一种解决接口返回慢的方式
    【Jmeter基础】 Linux上运行Jmeter
    【SpingBoot】 测试如何使用SpringBoot搭建一个简单后台1
    单例模式@Singleton在测试中的运用
    性能测试基础 ---TCP通信过程的状态码与过程,以及出现错误码的分析(TIME_WAIT,CLOSE_WAIT)
    Spring5源码分析(007)——IoC篇之加载BeanDefinition总览
  • 原文地址:https://www.cnblogs.com/huyibo/p/5475230.html
Copyright © 2020-2023  润新知