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

这篇博客探讨了C语言编程中常见的错误,包括引用错误的地址、读取未初始化内存、内存越界、操作指针对象不当、误解指针运算、引用不存在的变量以及malloc引起的内存问题。详细阐述了这些问题可能导致的后果和解决办法,提醒程序员注意这些潜在的陷阱,以提高代码质量和安全性。
摘要由CSDN通过智能技术生成

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<n;++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之后并不释放,造成内存泄漏

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仟各

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值