美文网首页
动态内存分配

动态内存分配

作者: 高念吖 | 来源:发表于2017-07-25 20:44 被阅读0次


    全局静态变量:存放全局变量和静态变量,空间由系统管理,程序执行时开辟空间,程序结束空间回收,在程序运行期间其空间一直存在

    常量区:存储常量,常量区的内容在程序运行期间不会发生改变,空间由系统管理,生命周期和系统的生命周期一致.

    代码区:存放程序执行的CPU指令,其实就是程序开发中所有的字符,代码标点等;

    栈区:在函数内部定义的局部变量局部数组,其内存都是开辟在栈区,栈区内存由系统管理,函数被调用时开辟空间,函数执行结束空间回收.

    堆区:空间开发人员手动开发,手动回收,是我们今后主要操作的内存区域;

    栈区空间

    int a = 0;//变量a的空间在栈区

    堆区

    关键字malloc:在堆区开辟空间的重要函数.malloc(size_t --size) size_t就是在堆区要开辟字节数.

    viod * 在此指的是泛型,其实就是开辟的空间任何类型数据都可以使用.

    int *p = malloc(4);//在堆取开4个字节的空间,里面存放 整形的数

    堆区开的空间 可以让任何类型的指针来接受

    练习1:在堆取上开辟3个短整形的数据的空间 并且赋值

    short *s = malloc(sizeof(short) * 3);

    *s = 7;

    *(s + 1) = 8;

    *(s + 2) = 9;

    printf("%d %d %d \n",*s,*(s+1),*(s+2));

    练习2:将10个int型数据,存入对区中

    int *p3 = malloc(sizeof(int) * 10);

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

    *(p3 + i) = arc4random() % ( 80 - 30 + 1 ) + 30;

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

    }

    free(p3);

    p3 = NULL;

    printf("");

    练习3:定义short指针 堆区内存 10 个整形数据  范围[20,50] 求出最大值

    int max = 0;

    short *p4 = malloc(sizeof(short) * 10);

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

    *p4++ = arc4random() % (50 - 20 + 1) + 20;

    if (*(p4 - 1) > max) {

    max  = *(p4 -  1);

    }

    printf("%d  ",*(p4 - 1));

    }

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

    p4--;

    }

    printf("\nmax = %d\n",max);

    释放内存 free(void *); 释放任意类型的内存

    //free(p4);

    安全起见,释放的只是平指向的空间的所有权,但是此时p4仍然指向已经释放的空间所以....

    p4 = NULL;

    并且,C语言中释放内存只是释放对此块的内存的所有权,但是不会清除内存中的数据,这就是为什么我们声明变量需要初始化赋初始值.

    注意  使用指针来释放指针所指的空间,必须保证指针指向的是空间的首地址

    练习4 在堆取开辟空间,存储5个整形数据,赋值范围[30,70],并对这几个数进行生序排序

    int *p5 = malloc(sizeof(int) * 5);

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

    *(p5 + i) = arc4random() % (70 - 30 + 1) + 30;

    }

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

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

    int temp = 0;

    if (*(p5 + j) > *(p5 + j + 1)) {

    temp = *(p5 + j);

    *(p5 + j) = *(p5 + j + 1);

    *(p5 + j + 1) = temp;

    }

    }

    }

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

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

    }

    练习5:有一个已知的整形数组元素个数为10,赋随机值[20,40],将大于30的数存储到堆区空间中

    int pArray[10];

    int count = 0;

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

    pArray[i] = arc4random() % (40 - 20 + 1) + 20;

    printf("%d ",pArray[i]);

    //这次for循环为了将大于30的数添加到堆区中

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

    if (pArray[i] > 30) {

    *p30++ = pArray[i];

    }

    }

    p30--;

    printf("\n");

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

    printf("%d ",*p30--);

    }

    练习6 :已知的字符串,其中包含数字和字符,提取其中的数字,存储到堆区空间上

    char str[] = "h4fjid6hfiu479jkx2";

    int num = 0; //存放数字的个数

    for (int i = 0; i < strlen(str); i++) {

    if (str[i] >= '0' && str[i] <= '9') {

    num++;

    }

    }

    //根据数字个数在堆区开空间,注意字符\0为了方便输出,我们可以把字符数组存储城字符串的格式

    char *p7 = malloc(num  + 1);// 1 要放\0

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

    if (str[i] >= '0' && str[i] <= '9') {

    *p7++ = str[i];

    }

    }

    //在末尾位置补上\0;

    *p7= '\0';

    //将指向最后一个元素首地址的指针设置重指向,指向字符串首地址

    p7 = p7 - num;

    printf("提取的数字为:%s\n", p7);

    free(p7);

    p7 = NULL;

    其他内存分配函数

    calloc(count , size);分配count个size大小的空间,比malloc多一个功能,就是clear清楚空间遗留数据的操作,但是执行效率较低,常用的还是malloc

    int *q = calloc(5, 4);

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

    q[i] = arc4random() % 21;

    printf("%d",q[i]);

    }

    free(q);

    q = NULL;

    realloc(<#void *#>, <#size_t#>)将指针p所指向的空间字节数重置成size个(size可以比原来字节数大也可以比原来空间字节数小)

    int *q1 = malloc(12);

    *q1 = 10;

    *(q1 + 1) = 20;

    *(q1 + 2) = 30;

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

    //重置为20 个字节

    q1 = realloc(q1, 20);

    *(q1 +3) = 67;

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

    //-------以上三个函数都是操作与堆区中的----------------------

    下面是内存操作函数(各种区域中都可使用)

    1.依据指定字节重新赋值的函数;memset (开始地址 , n size)

    //给定一个起始地址,将字节的数据设置为n,size为10,就意味着将10个字节的数据设置为0;

    printf("清零之前:%d\n",*q1);

    memset(q1, 0, 4);

    printf("清零之后:%d\n",*q1);

    2,memcpy(目的地址,原地址,size)

    //从源地址中拷贝size个字节的数据到目的地址中

    // 10 20 30

    memcpy(q1 + 1, q1 + 2, 4);

    printf("%d \n",*(q1 + 1));

    3,memcmp (目的地址 原地址  size)

    //将俩个地址开始的数据比较size个字节的大小

    *(q1 + 1) = 20;

    *(q1 + 2) = 30;

    int result  = memcmp(q1+1, q1+2, 4);

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

    练习7:定义俩个整形指针,分别用malloc calloc 对其分配3个整形氮元素的空间,但是malloc空间要使用memset做数据清空操作在赋值使用,随机对这俩块空间赋值[1,3],赋值后用memcmp比较俩个数组,如果值都相同就打印good,否则就打印no

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

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

    memset(q11, 0, 12);

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

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

    q22[i] = arc4random() % 3 + 1;

    printf("q22 = %d, q11 = %d\n",q11[i]);

    }

    int result1  = memcmp(q11, q22, 12);

    printf(result1==0 ? "Good" : "Oh");

    //静态变量 --- 全局区/ 静态区;

    static int a1 = 9;

    int *q6 = &a1;

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

    相关文章

      网友评论

          本文标题:动态内存分配

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