美文网首页
进击的NDK02-内存分配和字符

进击的NDK02-内存分配和字符

作者: Rc在努力 | 来源:发表于2018-08-29 21:16 被阅读9次

    C语言内存分配:

    • 栈区(stack)
      windows下,栈内存分配2M(确定的常数),超出了限制,提示stackoverflow错误 。自动分配,释放。
    • 堆区(heap)
      程序员需手动申请和分配释放,可使用的内存约是操作系统80%内存。
    • 全局区或静态区。
    • 字符常量区。
    • 程序代码区。
    void main(){
        //静态内存分配
        int a[1024 * 1024 * 10];
            
        //stack overflow错误,栈溢出
    
        getchar();
    
        return 0;
    }
    

    静态分配和动态分配

    • 静态内存分配,分配内存大小的是固定,这会带来:
      • 很容易超出栈内存的最大值
      • 为了防止内存不够用会开辟更多的内存,容易浪费内存
    • 动态内存分配,在程序运行过程中,动态指定需要使用的内存大小,手动释放,释放之后这些内存还可以被重新使用(活水)。

    创建一个数组,动态指定数组的大小

    void main(){
    
        //静态内存分配创建数组,数组的大小是固定的
        //int i = 10;
        //int a[i];//这样是不行的
    
        int len = 4;
    
        //动态开辟内存,大小len*4字节
        int* p = malloc(len * sizeof(int));
        //p是数组的首地址,p就是数组的名称
        //给数组元素赋值(使用这一块刚刚开辟出来的内存区域)
        int i = 0;
        for (; i < len ; i++){
            p[i] = rand() ;
            printf("%d,%#x\n", p[i], &p[i]);
        }
    
        //手动释放内存
        free(p);
    
        getchar();
    
    }
    

    重新分配内存

    重新分配内存的两种情况:

    • 缩小,缩小的那一部分数据会丢失。
    • 扩大,(连续的)
      • 如果当前内存段后面有需要申请的内存空间,直接扩展这段内存空间,realloc返回原指针。
      • 如果当前内存段后面的空闲字节不够,那么就使用堆中的第一个能够满足这一要求的内存块,将目前的数据复制到新的位置,并将原来的数据库释放掉,返回新的内存地址。
      • 如果申请失败,返回NULL,原来的指针仍然有效
    void main(){
        int len = 4;//第一次数组长度
    
        int* p = malloc(len*sizeof(int));
        //int *p = calloc(len, sizeof(int)); 作用与malloc一样
        int i = 0;
        for ( ;  i< len; i++)
        {
            p[i] = rand() % 200;
            printf("%d,%#x\n", p[i], &p[i]);
        }
    
        //内存不够用,扩大刚刚分配的内存空间
        int addLen = 6;
    
        //第一个参数,原来的内存指针
        //第二个,内存扩大后的总大小
        int *p2 = realloc(p, sizeof(int)*(len + addLen));
    
        if (p2 == NULL)
        {
            printf("重新分配失败");
        }
    
        //重新分配内存的两种情况:
        //缩小,缩小的那一部分数据会丢失
        //扩大,(连续的)
        //1.如果当前内存段后面有需要的内存空间,直接扩展这段内存空间,realloc返回原指针
        //2.如果当前内存段后面的空闲字节不够,那么就使用堆中的第一个能够满足这一要求的内存块,将目前的数据复制到新的位置,并将原来的数据库释放掉,返回新的内存地址
        //3.如果申请失败,返回NULL,原来的指针仍然有效
    
        //重新赋值
    
        i = 0;
    
        for (; i < len + addLen; i++){
            p2[i] = rand() % 200;
            printf("%d,%#x\n", p2[i], &p2[i]);
        }
        //手动释放内存
        if (p != NULL){
            free(p);
            p = NULL;
        }
        if (p2 != NULL){
            free(p2);
            p2 = NULL;
        }
        getchar();
    
    }
    

    内存分配的几个注意细节

    • 不能多次释放。
    • 释放完之后(指针仍然有值),给指针置NULL,标志释放完成。
    • 内存泄露(p重新赋值之后,再free,并没有真正释放内存)。

    字符数组存储字符串

    void main(){
        //char str[] = { 'c', 'h', 'i', 'n', 'a', '\0' };
        //char str[6] = { 'c', 'h', 'i', 'n', 'a' };
        char str[10] = "china";
        //可以修改
        str[0] = 's';
        printf("%s\n", str);
        printf("%#x\n", str);
        getchar();
    }
    

    字符指针

    void main(){
        //内存连续排列
        char *str = "how are you?";
    
        //不可以修改
        //str += 1;
        //*str = 'y';
        printf("%s\n", str);
        printf("%#x\n", str);
    
        //使用指针加法,截取字符串
        str += 3;
        while (*str){
            printf("%c",*str);
            str++;
        }
        printf("\n结束了");
        getchar();
    }
    

    strcat字符串拼接函数

    void main(void){
        char dest[50];  
        char *a = "china";
        char *b = " is powerful!";
        strcpy(dest, a);
        strcat(dest, b);
        printf("%s\n", dest);
    
        system("pause");
    }
    

    strchr在一个串中查找给定字符的第一个匹配之处

    void main(void){
        char *str = "I want go to USA!";
        printf("%#x\n", str);
        //U元素的指针
        //str+3
        char* p = strchr(str, 'w');
        if (p){
            printf("索引位置:%d\n", p - str);
        }
        else{
            printf("没有找到");
        }
    
        system("pause");
    }
    

    相关文章

      网友评论

          本文标题:进击的NDK02-内存分配和字符

          本文链接:https://www.haomeiwen.com/subject/zwtcwftx.html