C语言进阶课程学习记录-内存操作经典问题分析

发布于:2024-04-20 ⋅ 阅读:(147) ⋅ 点赞:(0)

C语言进阶课程学习记录-内存操作经典问题分析


本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程,图片全部来源于课程PPT,仅用于个人学习记录

在这里插入图片描述

在这里插入图片描述

实验-示例1

#include <stdio.h>
#include <malloc.h>


int main()
{
    int* p1 = (int*)malloc(40);
    int* p2 = (int*)1234567;//野指针
    int i = 0;

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

    for(i=0; i<40; i++)//内存越界,改写非法的内存地址
    {
        *(p1 + i) = 40 - i;
    }

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

    for(i=0; i<40; i++)
    {
        p1[i] = p2[i];//使用了已经释放的空间
    }

    return 0;
}

优化

#include <stdio.h>
#include <malloc.h>

int arr[40]={1,2,3,4,5,6,7};
int main()
{
    int* p1 = (int*)malloc(sizeof(int)*40);
    int* p2 = arr;//
    int i = 0;

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

    for(i=0; i<40; i++)
    {
        *(p1 + i) = 40 - i;
    }

    free(p1);
    p1=NULL;
    printf("%p\n",p1);

    for(i=0; i<40; i++)
    {
        p1[i] = p2[i];//使用了已经释放的空间
    }

    return 0;
}

在这里插入图片描述

实验-示例2

#include <stdio.h>
#include <string.h>
#include <malloc.h>

struct Student
{
    char* name;
    int number;
};

char* func()
{
    char p[] = "D.T.Software";

    return p;
}

void del(char* p)
{
    printf("%s\n", p);

    free(p);
}

int main()
{
    struct Student s;//未初始化,有野指针
    char* p = func();//野指针

    strcpy(s.name, p);//使用野指针

    s.number = 99;

    p = (char*)malloc(5);

    strcpy(p, "D.T.Software");//内存越界

    del(p);

    return 0;
}

优化

#include <stdio.h>
#include <string.h>
#include <malloc.h>

struct Student
{
    char* name;
    int number;
};

char* func()
{
    char p[] = "D.T.Software";

    return p;
}

void del(char* p)
{
    printf("%s\n", p);

    free(p);
    p=NULL;
}

int main()
{
    struct Student s;
    s.name=(char*)malloc(sizeof(char)*20);
    //char* p = func();

    strcpy(s.name, "D.T.Software");//
    del(s.name);


    s.number = 99;

    char *p = (char*)malloc(25);

    strcpy(p, "D.T.Software");

    del(p);

    return 0;
}

    /*
    output:
D.T.Software
D.T.Software
    */

在这里插入图片描述

实验-示例3

#include <stdio.h>
#include <malloc.h>

void test(int* p, int size)
{
    int i = 0;

    for(i=0; i<size; i++)
    {
        printf("test:%d\t", p[i]);
    }

    free(p);
}

void func(unsigned int size)
{
    int* p = (int*)malloc(size * sizeof(int));
    int i = 0;

    if( size % 2 != 0 )//奇数时返回,没有释放空间
    {
        return;
    }

    for(i=0; i<size; i++)
    {
        p[i] = i;
        printf("func:%d\t", p[i]);
    }

    free(p);
}

int main()
{
    int* p = (int*)malloc(5 * sizeof(int));

    test(p, 5);
    printf("\n");

    free(p);

    func(9);
    printf("\n");
    func(10);
    printf("\n");

    return 0;
}



    /*
    output:
test:6755432    test:6761736    test:0  test:0  test:0

func:0  func:1  func:2  func:3  func:4  func:5  func:6  func:7  func:8  func:9
    */

实验-示例4

#include <stdio.h>
#include <malloc.h>

struct Demo
{
    char* p;
};

int main()
{
    struct Demo d1;
    struct Demo d2;

    char i = 0;

    for(i='a'; i<'z'; i++)
    {
        d1.p[i] = 0; //使用野指针
    }

    d2.p = (char*)calloc(5, sizeof(char));

    printf("%s\n", d2.p);

    for(i='a'; i<'z'; i++)
    {
        d2.p[i] = i; //内存越界
    }

    free(d2.p);

    return 0;
}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

小结

内存错误的本质源于指针保存的地址为非法值
指针变量未初始化,保存随机值
指针运算导致内存越界
内存泄漏源于malloc和free不匹配
当malloc次数于free时,产生内存泄漏
当malloc次数于free时,程序可能崩溃