C语言进阶课程学习记录-内存操作经典问题分析
- 实验-示例1
- 优化
- 实验-示例2
- 优化
- 实验-示例3
- 实验-示例4
- 小结
本文学习自狄泰软件学院 唐佐林老师的 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时,程序可能崩溃