C语言-非法内存操作分析
•结构体成员指针未初始化
•没有为结构体指针分配足够的内存空间
struct Demo
{
int* p;
};
int main()
{
struct Demo d1;
struct Demo d2;
int i = 0;
for(i=0; i<10; i++)
{
d1.p[i] = 0; // OOPS! 对为初始化的指针赋值
}
d2.p = (int*)calloc(5, sizeof(int));
for(i=0; i<10; i++)
{
d2.p[i] = i; // OOPS! 数组越界,非法操作
}
free(d2.p);
return 0;
}
•内存分配成功,但并未初始化
int main()
{
char* s = (char*)malloc(10); //并未初始化 内存申请成功后一定要初始化
printf(s); // OOPS! C语言字符串还是字符数组区别在于结尾有没有\0 结束符 这里printf打印长度不一定 ,内容无法预估
free(s);
return 0;
}
•数组越界
void f(int a[10])
{
int i = 0;
for(i=0; i<10; i++)
{
a[i] = i; // OOPS!
printf("%d\n", a[i]);
}
}
int main()
{
int a[5];
f(a); //数组在作为函数形参时退化为指针 数组越界操作
return 0;
}
•内存泄漏错误
void f(unsigned int size)
{
int* p = (int*)malloc(size*sizeof(int));
int i = 0;
if( size % 2 != 0 )
{
return; // OOPS! 返回造成申请的空间没有释放 设计函数时最好是单入口,单出口。这个程序单入口,双出口。
}
for(i=0; i<size; i++)
{
p[i] = i;
printf("%d\n", p[i]);
}
free(p);
}
int main()
{
f(9);
f(10);
return 0;
}
•多次释放指针
void f(int* p, int size)
{
int i = 0;
for(i=0; i<size; i++)
{
p[i] = i;
printf("%d\n", p[i]);
}
free(p);
}
int main()
{
int* p = (int*)malloc(5 * sizeof(int));
f(p, 5);
free(p); // OOPS! 谁申请谁释放,不要重复释放内存 ,不要在main中申请的f中释放。 多次释放指针会造成程序异常退出。
return 0;
}
•使用已经释放的内存
void f(int* p, int size)
{
int i = 0;
for(i=0; i<size; i++)
{
printf("%d\n", p[i]);
}
free(p);//p会变为一个野指针
}
int main()
{
int* p = (int*)malloc(5 * sizeof(int));
int i = 0;
f(p, 5);
for(i=0; i<5; i++)
{
p[i] = i; // OOPS! 一直在操作一个野指针 影响可重可轻
}
return 0;
}

浙公网安备 33010602011771号