栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

总结C程序中常见的与内存有关的错误

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

总结C程序中常见的与内存有关的错误

1.引用错误的地址

在日常的程序编写中,容易由于粗心出现的一个问题:没有映射到有真正意义的数据
比如:
scanf(“%d”,val);
由于粗心导致我们将val的地址误写为val这个值,那么在执行scanf的时候,就会把val的这个值解释为地址并去寻找这个地址,然后去覆盖那个地址的值。

2.读未初始化的内存

刚接触C语言的同学总会如认为指针所指向的地址的值总是为0,其实并不是这样的,如果没有进行初始化,那么指针指向的地址的值是一个随机值,并不是0

3.内存越界

(1)栈缓冲区溢出
比如程序不检查输入串的大小就直接写入栈中的目标缓冲区,当输入串过大超过目标缓冲区的大小时,就会出现溢出。
(2)由于没有控制好变量的范围导致越界,从而覆盖非法内存的内容
(3)假设指针和它指向的对象是相同大小的
在有些机器上,指针的大小和int类型的大小是不一样的,像Core i7这样的机器上,指针大于int。如果不明确这一定,就容易造成错误。

例如:

int** makeArray(int n,int m)
{
    int **A(int**)malloc(n*sizeof(int));
    for(int i=0;i
         A[i]=(int*)malloc(m*sizeof(int));
    }
    return A;
}

在上面的示例中,“ int **A(int**)malloc(n*sizeof(int));”是错误的,应该是: int **A(int**)malloc(n*sizeof(int*));
错误的代码误认为指针和它所指向的对象相同大小,所以申请了n*sizeof(int)个字节,这里假设n=4,所以申请了16个字节,但是当在Core i7这样的机器上时,指针大于int,本来应该申请的字节大于16,但是写成 int **A(int**)malloc(n*sizeof(int));之后,就只申请了16个字节,申请的空间不足,那么在循环中,将写到超出A数组结尾的地方。

4.引用指针,而不是它所指向的对象

需要注意C操作符的优先级和结合性
比如:
size是一个指针,size是这个指针所指向的对象,当执行size–的时候,如果本意是想让size指针所指向的对象的值减一,但是事与愿违,因为星号和减减的优先级相同,从右向左结合,意思就变为:指针减一,然后得出指针所指的对象。
所以需要明确操作符的优先级,避免因此导致错误。

5.误解指针运算

指针都是四个字节,所以指针加一,就是让指针移动大所指类型对象的下一个对象。
比如:

int *fun(int* p,int val)
{
     while(*p&&*p!=val)
     {
         p+=sizeof(int);//应该是p+=1;
     }
     return p;
}

上述代码中p加4,意思是指向当前对象之后的第四个对象,而不是下一个对象。

6.引用不存在的变量

典型错误:在定义的一个函数中,当我们定义了一个局部变量,然后在函数返回的时候返回这个局部变量的地址
原因是:局部变量存放在栈中,函数调用结束,那么这个函数中定义的局部变量的生存期就到了,就会被释放,如果我们还返回一个局部变量的地址,等于返回了一个失效地址,并没有什么意义,甚至会给程序带来重大问题。

7.使用malloc造成的内存问题

(1)引用已经调用free()函数释放的块
(2)使用malloc之后并不释放,造成内存泄漏

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/913426.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号