美文网首页
动态内存管理

动态内存管理

作者: lxr_ | 来源:发表于2021-10-12 21:40 被阅读0次
//函数原型:void* malloc(size_t size)  void* 可以转换为任意类型指针
//malloc函数向申请分配size个字节的内存空间,并返回一个指向这块空间的指针(转换后),但不会帮我们初始化空间
//如果函数调用失败,返回值为NULL,若size设为0,返回值也可能是NULL,但不意味着函数调用失败
//如果申请内存后,使用完没有及时释放,容易造成内存泄漏,程序崩溃
//所以malloc和free成对出现

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    //***********malloc和free******************
    int* ptr;
    int num = 123;

    ptr = (int*)malloc(sizeof(int));  //申请内存后void*-->int*
    if (ptr == NULL)
    {
        printf("分配内存失败\n");
    }
    else
    {
        printf("请输入一个整数:");
        scanf_s("%d", ptr);//scanf不会检查边界,可能会造成数据溢出,
        printf("输入的整数是:%d\n", *ptr);

        //ptr = &num;                   //指向了其他内存,原内存无法释放,导致隐式的内存泄漏,造成程序崩溃
        //printf("num:%d\n", *ptr);    //

        free(ptr);   //free函数指向ptr指向的内存空间,该内存空间由malloc,calloc或realloc函数申请
                     //否则,该函数将导致未定义行为,如果ptr为NULL,则不执行任何操作。
                     //该函数并不会修改ptr参数的值,调用后它仍然指向原来的地方,只不过变为非法空间,访问不到原来的数据
                     
    }

    //****************小实验:实现动态录入多个整数***********
    int* p = NULL;
    int num1;
    printf("请输入待录入整数的个数:");
    scanf_s("%d", &num1);

    p = (int*)malloc(sizeof(int) * num1);
    if (p == NULL)
    {
        printf("内存申请失败");
    }
    else
    {
        for (int i = 0; i < num1; i++)
        {
            printf("请输入第%d个整数:", i + 1);
            scanf_s("%d", p + i);
        }

        printf("你输入的全部整数为:");
        for (int i = 0; i < num1; i++)
        {
            printf("%d ", p[i]);
        }
        printf("\n");
        free(p);
    }

    //****************其他内存管理函数**************
    //以mem开头的函数(返回值为void*),包含于string.h中,与str开头的函数(返回值为字符指针char*)区别开
    //处理内存空间用mem开头,处理字符串用str开头

    //memset  使用一个常量字节填充内存空间
    //memcpy  拷贝内存空间
    //memmove 拷贝内存空间
    //memcmp  比较内存空间
    //memchr  在内存空间搜索一个字符

    int* pp = NULL;
    pp = (int*)malloc(10 * sizeof(int));

    if (pp == NULL)
    {
        printf("内存申请失败\n");
    }
    else
    {
        memset(pp, 0, 10 * sizeof(int));  //申请的这段内存初始化为0
        for (int i = 0; i < 10; i++)
        {
            printf("%d ", pp[i]);  //0 0 0 0 0 0 0 0 0 0
        }
        printf("\n");

        free(pp);

    }

    //void* calloc(size_t nmemb,size_t size);calloc函数在内存中动态申请nmemb个长度为size的连续内存空间
    //即申请的内存空间总尺寸为nmemb*size,这段内存空间全部被初始化为0
    //与malloc的重要区别是会执行初始化为0

    int* p1 = (int*)calloc(8, sizeof(int));
    if (p1 == NULL)
    {
        printf("内存申请失败");
    }
    else
    {
        for (int i = 0; i < 8; i++)
        {
            printf("%d ", p1[i]); //0 0 0 0 0 0 0 0
        }
        printf("\n");
        free(p1);
    }

    //memcpy实现内存拷贝
    int* p2 = NULL;
    int* p3 = NULL;

    p2 = (int*)malloc(10 * sizeof(int));
    if (p2 == NULL)
    {
        printf("内存申请失败\n");
    }
    else
    {
        //p2....
        //此处p2一系列操作后,若申请的p2指向的内存不够用
        p3 = (int*)malloc(20 * sizeof(int));

        if (p3 == NULL)
        {
            printf("内存申请失败\n");
        }
        else
        {
            //将p2的数据拷贝到p3中,并释放p2
            memcpy(p3, p2, 10);
            free(p2);

            //对p3进行操作
            //p3....

            //释放p3
            free(p3);
        }
    }

    //void* realloc(void* ptr,size_t size)实现ptr指向的内存重新分配size大小
    //如果新分配的内存空间大小size比原来的大,则原来内存中的数据不会发生改变,否则会导致数据丢失
    //如果ptr为NULL,则相当于调用malloc(size)
    //如果size为0,且ptr不为NULL,则该函数相当于free(ptr)
    //除非ptr参数为NULL,否则ptr的值必须由先前调用malloc,calloc或realloc函数返回的

    //*************小实验:将用户输入不断存入内存,-1退出********
    int n;
    int count = 0;
    int* pr = NULL;   //必须初始化为NULL,realloc开始调用时相当于malloc
    do
    {
        printf("请输入一个整数,-1表示结束\n");
        scanf_s("%d", &n);
        count++;

        pr = (int*)realloc(pr, count * sizeof(int));

        if (pr == NULL)
        {
            printf("内存申请失败\n");
        }
        else
        {
            pr[count - 1] = n;  //前面的数据会自动存入新的内存,将最新数据手动存入
        }

    } while (n != -1);

    printf("输入的所有整数为:\n");
    for (int i = 0; i < count - 1; i++)  //输出所有整数,不包括表示结束的数-1
    {
        
        printf("%d ", pr[i]);
    }
    printf("\n");

    free(pr);
    
    return 0;
}

相关文章

网友评论

      本文标题:动态内存管理

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