不疯不成魔

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
//
//  main.m
//  LessonMemory
//
//  Created by laouhn on 15/7/28.
//  Copyright (c) 2015年 池海涛. All rights reserved.
//

#import <Foundation/Foundation.h>
struct student {
    char name[20];
    char Sex;
    int age;
};
typedef struct student Student;
void fun2()
{
    printf("sosososososos");
}
int main(int argc, const char * argv[]) {
 
#pragma mark--栈区:函数参数或者是局部变量存储的区域
    /*
     >栈区的特点
     1.分配原则:有高到底分配,由低到高存取
     2.函数调用的过程就是出栈的过程.调用函数时入栈,系统会给该函数分配所需的空间;函数调用结束,出栈,系统会将分配的空间回收.
     3.栈区空间是有限的 8M左右,之所以程序运行不会崩溃是因为----栈区空间在频繁的开辟以及释放
     4.对于栈区空间的管理是由系统进行管理,不需要我们进行管理
     int a = 10;
     int b = 10;
     int c = 10;
     printf("a的地址 %p\nb的地址%p \nc的地址 %p\n",&a,&b,&c);
     */
    

    
    
    
    
    
#pragma mark---标记2 静态区:全局变量和静态变量存储的区域
    /*
     静态变量的特点:
     1.静态变量只初始化一次
     2.惊天变量如果不赋值,默认为0
     3.静态变量空间一旦开辟,不会回收.在程序执行周期中都存在
     
     
     静态区分为两部分:一部分存储赋值的全局变量和静态变量,另一部分存储没有赋初值的全局变量和静态变量
     
     */
    //static int num = 0;//由static 修饰的变量就是静态变量,局部静态变量.
    
#pragma mark ----常量区
    //常量区:存储常量,整型常量,浮点型常量,字符常量,字符串常量
    //printf("%p\n","iOS");
    //char *str = "iPhone";
    //str[0] = 'a';//常量区内容是只读的,不能被修改
    //printf("%s\n",str);
#pragma mark ++++变量和常量
    //变量:可以被修改的量,变量相当于一个容器,容器本身不发生变化,变化的是容器中存储的内容
    //常量:不可以被改变的量
    
    //const 修饰变量,一旦变量被const修饰,变量就会当做常量来使用.
    
    //口诀:看const修饰的是谁,const修饰谁,谁就不会发生改变,如果const修饰的内容中存在基本数据类型,将基本数据类型忽略掉
    //面试题
    //区分下列变量谁不会放生改变
    
//    int a = 10;
//    int b = 30;
//    const int *p1 = &a;
    
    
    //1.const 修饰的是*p1  *p1 = 20 是错误的 *p1 处于只读状态
//     a = 39;
//    printf("%d ",*p1);
//    p1 = &b;
    
    //2.const 修饰 p2,此时p2 处于只读状态,不能被重新赋值
//    int *const p2 = &a;
//    //p2 = &b;
//    *p2 = 20;
    
    
    //3.const 修饰的 p3 ,此时*p3 处于只读状态,不能被重新赋值,此时与第一种情况相同
    //int const *p3 = &a;
    
    //4.const 修饰 *p4 和p4,此时*p4 和p4都处于只读状态,都不能被重新赋值
    //const int *const p4 = &a;
    
    
    //char str1[] = "iPhone"; //此时,常量去得'iPhone',拷贝一份给栈区的数组str进行保存
    
#pragma mark ---代码区:所有的语句编译成cpu指令存储在该区域
    
    //printf("%p\n",fun2);
#pragma mark ----堆区:由我们(iOS开发人员)自主管理的区域(手动开辟,手动释放);
//内存分配函数
    //void *malloc(unsigned int size);
    //void *表示是无类型的指针,可以转化为任意类型的指针.
    //malloc函数的作用: 在堆区开辟指定size 个字节的空间,并把空间的首地址返回
    //int *p = NULL;
    //指针变量p存储的是malloc出来的 堆区4个空间的地址
//    p = malloc(4);
//    *p = 3;
//    printf("%d\n", *p);
     // char *str = malloc(8);
//    printf("%p \n", str);//指针变量 str中存储的是 堆区的地址
//    printf("%p \n",&str);//指针变量 str自己的地址
    //char string[8200 * 1024] = {'\0'};
    //iPhone 存储到该空间
   // strcpy(str, "iPhone");
    //strcpy(str, "Win Phone");
    //该方式不合法, 因为拥有权限的空间只有 8 个字节,超出的不在字节控制范围之内
   // int *a = malloc(4);
   // short *b = malloc(4);
    //a 分配了一块内存区域,可存放一个int 类型的数据, b 可以存放两个 short类型的数据
    //printf("%s \n",str);
    
    
//    
//    int *p = malloc(6);
//    *p = 7;
//    p[1] = 5;
    //*(p + 1) --p[1],不可以这样写,空间不够,指针只开辟了6个空间,而第二个元素需要4个字节占用了不合法的空间
    
    
    //分配一个结构体内存
  //  Student *stu = malloc(sizeof(Student));
    //分配一个结构体数组内存
    //Student *stuArray = malloc(sizeof(Student) * 5);
    
    //void free(void *) ;//将指定地址所对应的空间释放(还给系统);
    //int *p = NULL;
   // p = malloc(6);//该空间,系统找不到了,照成内存泄露
    //p = malloc(10);
    //free(p);//开辟之后,记得释放,如果不释放就会出现问题:内存泄露
    //free(p);过度释放,照成程序崩溃
   // p = NULL;//将空间释放之后,将指针置为NULL 防止野指针
   // free(p); //不会报错,p 指向无效空间
    //free(p);
    //free(p);
    //free 函数的作用是释放内存,内存释放是标记删除
    
    //注意:释放一定要等到不使用的时候释放
    
    //堆区内存问题:
    /*
     1.野指针:访问一块没有权限的空间
     2.过度释放:一块空间被释放了多次,----过度释放会照成程序立即crash
     3.内存泄露:空间没有释放,造成内存的堆积,不会立即crash,存在安全隐患
     */
 /*
    int *p = malloc(5 * sizeof(int));
    
    for (int i = 0; i < 5; i++) {
        *(p + i) = arc4random() % (40 - 20 + 1) + 20;
    }
    
    for (int i = 0 ; i < 5 - 1; i++) {
        for (int j = 0; j < 5 - 1 - i; j++) {
            if (*(p + j) > *(p + j + 1)) {
                int temp = *(p + j);
                *(p + j) = *(p + j + 1);
                *(p + j + 1) = temp;
            }
        }
    }
    for (int i = 0; i < 5; i++) {
        printf("%d ",*(p + i));
    }
    
    
    //释放 手动开辟的空间
    free(p);
    p = NULL;

    */
    /*
    int i = 0;
    int k = 0;
    int j = 0;
    char str[] = "13s4sf3f24";
    // int a[20] = {0};
    char *p = NULL;
    while (str[i] != '\0') {
        if (str[i] >= '0' && str[i] <= '9') {
            //a[k++] = str[i];
            k++;
            
        }
        i++;
    }
    i = 0;
    //分配空间,按照字符串进行处理
    printf("数字个数=%d \n",k);
    p = malloc((k + 1)*sizeof(int));
    
   
        while (str[i] != 0) {
            if (str[i] >= '0' && str[i] <= '9') {
                *(p + j) = str[i];
                j++;
            }
            i++;
        }
    *(p + j) = '\0'; //最后添加\0
   
    printf("%s\n", p);
    
    free(p);
    p = NULL;
    
    */
    //内存分配的另一个方式: calloc ---c是clear 的首字母,该函数的作用与malloc的作用,但是多了一步清零操作,该函数的执行效率比malloc低
    //int *p = calloc(10,4);//第一参数代表分配空间的个数,第二个参数代表每个空间所占的字节数
    //使用完,要释放
    //free(p);
    //防止野指针
    //p = NULL;
    
    //void *realloc(void *p,unsigned newSize);
    //内存重新分配的函数,先以之前的内存空间的首地址为基准进行重新划分.如果原来空间够用,直接返回原来空间的首地址,如果原来空间不够用,就重新寻找新的空间进行划分,并返回这块空间的地址,另外,realloc 内部集成了将之前内存free的操作.
    
//    char *p = malloc(10);
//    char *p1 = realloc(p, 20);//参数1 是之前空间的首地址,参数2是重新开辟空间的大小
//    printf("p的地址是:%p\np1的地址是:%p",p,p1);

//内存操作函数
    //----memset(void *,int,size_t),为malloc分配的空间执行清理操作,参数1代表从哪个位置开始清理,参数2代表清理时使用什么值代替,参数3代表清理多大的空间
    
//    char *p = malloc(3);
//    memset(p, 0, 3);//从p的位置开始清理,清理3个字节,把每个字节上值赋值为0
//    free(p);
//    p = NULL;

    //
    //----memcpy(void *dest,const void *source, size_t); 从source指向的内存开始 拷贝 size 个字节大小,到dest 指向的内存.
//    char str[] = "ZZS1570732";
//    char string[] = "KONGKONG";
//    memcpy(str, string, 4);
//    printf("%s\n%s",str,string);
    //int memcmp(const void *buf1,const void * buf2,unsigned int count);从给定得两个地址buf1,buf2,从开始进行比较,比较count个字节返回第一个不相等的字节空间的差值.
    
    //定义两个 整型指针,分别用malloc、calloc对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行 赋值 随机范围1-3,赋值后用memcmp比较两个数组。如果相同打印Good!否则打印Failed...
    
    int *p = malloc(3 * sizeof(int));
    int *p2 = calloc(3, 4);
    printf("%d",*p);
    printf("%d",*p2);
    memset(p, 0, 12);
    for (int i = 0; i < 3; i++) {
        p[i] = arc4random() % (3 - 1 + 1) + 1;
        p2[i] = arc4random() % (3 - 1 + 1) + 1;
        printf("%d %d \n",p[i],p2[i]);
    }
    //比较
    int result = memcmp(p,p2 , 12);
    if (result == 0) {
        printf("GOOD!");
    }else
        printf("BAD!");
    free(p);
    free(p2);
    p = NULL;
    p2 = NULL;
    return 0;
}
//释放

 

posted on 2015-07-30 08:54  不疯不成魔  阅读(238)  评论(0编辑  收藏  举报