首页 > 代码库 > Lesson(DynamicMerry)动态内存分配

Lesson(DynamicMerry)动态内存分配

//  main.m

//  1-27随堂笔记

//讲师: 小辉

//笔者: 王学文

//  Created by lanouhn on 15/1/27.

//  Copyright (c) 2015年 lanouhn. All rights reserved.

//动态内存分配(DynamicMerry)

 

#import <Foundation/Foundation.h>

 

void test() {

    int x = 10;

    int y = 20;

}

 

//函数返回栈区的数据,是不安全的;一in为展区的数据随着函数执行结束,也会由系统自动回收回去,不能够办证一直能够使用

int comeBack() {

    int x = 0;

    return x;

}

 

int mac = 1020;//全局变量

 

 

int main(int argc, const char * argv[]) {

    /*

    //内存区域划分(地址由高到低)

    //1. 栈区

    //2. 堆区

    //3. 静态区(全局区)

    //4. 常量区

    //5. 代码区

    

    //栈区:

    //函数中定义的局部变量由系统在栈区分配内存

    //开发人员不用关心系统如何分配内存,完全由系统分配和释放内存

    int a  =10;

    printf("%p\n", &a);

    //栈区内的数据以栈的形式存储

    //栈的特点: 先进后出

    

    int b = 15;

    

    test();

    

    int x = comeBack();

    

    //静态全局区

    //全局变量和用static修饰的变量都由系统的静态全局区存放

    //静态全局区的所分配的内存,直到程序结束才能被释放

    printf("%p\n", &mac);

    

    //用static修饰的变量

    //1. 存放在静态全局区

    //2. 只能被初始化一次

    //3.如果没有赋初值, 默认为0

    static int apple = 123;

    printf("%p\n", &apple);

    

    for (int i = 0; i < 5; i++) {

        static int n = 0;//只能被初始化一次,默认初值是0;

        printf("%d\n", n);

        n++;

    }

    

    //常量区

    //1. 常量(‘a‘, 123, 34.5, "iphone")都被存到常量区

    //常量区由系统管理

    char *p = "IOS";

    printf("%p\n", p);

    //常量区的数据,只能够读,不能修改

    printf("%c\n", *p);

    // *p = ‘a‘;//error

    

    

    //代码区

    //程序中的函数和语句会被编译成CPU指令存在代码区

    //代码区有系统控制

    

    //堆区

    //有开发人员手动申请,手动控制

    

    //申请内存函数

    //void *malloc(<#size_t#>)

    //返回值类型: void * (泛类型), 泛型指针可以装换成任意一种指针类型

    //函数名: malloc

    //参数类型: size_t, unsigned int

    //参数含义: 多少个字节

    

    int *p1 = malloc(4);

    printf("%p\n", p1);

    *p1 = 10;

    

    char *p2 = malloc(7);

    strcpy(p2, "iphone");

    printf("%s\n", p2);

    

    *p2 = 66;

    printf("%s\n", p2);

    

    p2[3] = ‘\0‘;

    printf("%s\n", p2);

    

    strcpy(p2 + 2, "abcd"); //越界

    printf("%s\n", p2);

    

    strcpy(p2, p2 + 2);

    printf("%s\n", p2);

    

    printf("%c\n", *(p2 + 5));

    

    char *p3 = malloc(7);

    strcpy(p3, "iphone");

    printf("%p\n", p3); //堆区的地址

    printf("%p\n", &p3); //栈区的地址

    

    //内存泄露: 内存区域一直被占用,得不到释放;

    

    //内存释放的函数

    //free(void *)

    

    //把对应的内存区域的标记改为可用

    free(p3);

    //实际上指针p3的内容被清除,需要置空

    p3 = NULL;

    

    

    //使用动态内存存储10个整形的随机数,取值范围[1, 27]

    

    int *p4 = malloc(40);

    //1.

    for (int i = 0; i < 10; i ++) {

        *(p4 + i) = arc4random() % 27 + 1;

        printf("%d ", *(p4 + i));

    }

    //2.

//    for (int i = 0; i < 10; i++) {

//        *p = arc4random() % 27 + 1;

//        printf("%d ", *p4);

//        p4++;

//    }

    free(p4);

    p4 = NULL;

    

    

    //有一字符串,其中包含数字,提取其中的数字,要求动态分配内存保存,

    //提示: 先计算出有几个数字,然后根据数字的个数开辟空间‘

//    char arr[13] = "ab1cd2ef3gh4";

//    char count[13] = {0};

//    int i = 0;

//    int j = 0;

//    while (arr[i] != ‘\0‘) {

//        if (arr[i] >= ‘0‘ && arr[i] <= ‘9‘) {

//            

//            count[j] = arr[i];//error

//            j++;

//        }

//        i++;

//    }

//    char *p5 = malloc(sizeof(char) * (count[j] + 1));

//    p5 = count;

//    *(p5 + j + 1) = ‘\0‘;

//    printf("%s\n", p5);

//    free(p5);

//    p5 = NULL;

    

    //2.标准方法

    char string[] = "12ab34cd5ef6gs8gs5s14f5s";

    int i = 0, count = 0;

    while (string[i] != ‘\0‘) {

        if (string[i] >= ‘0‘ && string[i] <= ‘9‘) {

            count++;

        }

        i++;

    }

    printf("%d\n", count);

    char *p5 = malloc(sizeof(char) * (count + 1));

    int j = 0, k = 0;

    while (string[j] != ‘\0‘) {

        if (string[j] >= ‘0‘ && string[j] <= ‘9‘) {

            *(p5 + k) = string[j];

            k++;

        }

        j++;

    }

    *(p5 + k) = ‘\0‘;

    printf("%s\n", p5);

    free(p5);

    p5 = NULL;

    

    //输入3个单词,动态分配内存保存单词,并在最后输出

//    printf("请输入三个单词:");

//    char array[3][10] = {0};

//    for (int i = 0; i < 3; i++) {

//        scanf("%s", array[i]);

//    }

//    char *word[3] = {0};

//    for (int i = 0; i < 3; i++) {

//        word[i] = malloc(strlen(array[i]) + 1);

//        strcpy(word[i], array[i]);//?

//     }

//    for (int i = 0; i < 3; i++) {

//        printf("%s\n", word[i]);

//    }

//    for (int i = 0; i < 3; i++) {

//        free(word[i]);

//        word[i] = NULL;

//    }

    

    //2.标准方法

    //临时字符

    char temp[100] = {0};

    //指针数组,用于存放为3个单词在堆区申请内存的 首地址

    char *words[3] = {0};

    for (int i = 0; i < 3; i++) {

        //输入字符

        scanf("%s", temp);

        //strlen计算字符串不包括‘\0‘,需要加1

        unsigned long length = strlen(temp) + 1;

        //把堆区申请代的内存首地址 存到指针数组中

        words[i] = malloc(sizeof(char) * length);

        //进行字符串拷贝

        strcpy(words[i], temp);

        printf("存入字符串:%s\n", words[i]);

    }

    //释放内存, 需要先找到刚才申请的堆区的首地址, 首地址都在指针数组存放, 遍历指针数组, 释放内存

    for (int i = 0; i < 3; i++) {

        free(words[i]);

        words[i] = NULL;

    }

    

    

    //动态内存的其他函数

    //void *calloc(n, size)

    //和malloc一样,嗾使申请内存, 并且calloc申请内存后, 会对内存里的内容做清空的操作,效率要比malloc低

    //n: 个数

    //size: 字节数

    //calloc申请的内存字节数 = n * size

    int *p6 = calloc(5, 4);

    free(p6);

    p6 = NULL;

    

    

//void *realloc(p, size)

    //从给定的位置p, 开始申请size个字节

    //从地址p向后申请size个字节,如果后面可用的字节够的话, 就申请内存,并放回当前的指针p; 如果不够的话,会在去内存中找一块连续的空间,如果找到,就返回这一块连续空间的首地址,并且把之前所占用得内存释放

    int *p7 = malloc(2);

    printf("%p\n", p7);

    p7 = realloc(p7, 4000);

    printf("%p\n", p7);

    

    //void memset(p, c, n)

    //从指针p的位置开始初始化n个字节的内存,把内容改成c

    char *p8 = malloc(3);

    memset(p8, 66, 2);

    *(p8 + 2) = ‘\0‘;

    printf("%s\n", p8);

    

    //void memcpy(<#void *#>dest, <#const void *#>source, n);

    //从指针source的位置开始,向指针dest位置,拷贝n个字节的内容

    char str1[] = "ABC";

    char str2[] = "123";

    memcpy(str1, str2, 2);

    printf("%s\n", str1);

    

    //int memcmp(p1, p2, n)

    //比较p1和p2指向的内存所存放的内容是否相同, 比较n个字节, 相同的话返回0, 不同返回差值

    int *a1 = malloc(4);

    *a1 = 1;

    int *a2 = malloc(4);

    *a2 = 3;

    int result = memcmp(a1, a2, 1);

    printf("%d\n", result);

    */

    

//    定义两个 整型指针,分别用malloc、calloc对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行 赋值 随机范围1-3,赋值后用memcmp比较两个数组。如果相同打印Good!否则打印Failed...    

    

    int *a = malloc(sizeof(int) * 3);

    int *b = calloc(3, sizeof(int));

    memset(a, 0, sizeof(int) * 3);

    for (int i = 0; i < 3; i++) {

        *(a + i) = arc4random() % 3 + 1;

        *(b + i) = arc4random() % 3 + 1;

        printf("%d %d\n", *(a + i), *(b + i));

    }

    int n = memcmp(a, b, sizeof(int) * 3);

    if (n == 0) {

        printf("Good!\n");

    } else {

        printf("Failde...\n");

    }

    free(a);

    a = NULL;

    free(b);

    b = NULL;

 

    

    return 0;

}

 

Lesson(DynamicMerry)动态内存分配