首页 > 代码库 > 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)动态内存分配