zoukankan      html  css  js  c++  java
  • 使用malloc遇到的奇怪问题——调试的时候正确,运行的时候结果就不对了

    为了偏于叙述,我将遇到问题的源代码进行了简化,只保留了出现问题的根本语句。

    给出代码:

    #include <stdio.h>

    #include <stdlib.h>

    #define N 100

    struct A

    {

    int a[N];

    };

    int main()

    {

    struct A* p;

    p = (struct A*)malloc(sizeof(struct A*));

    for (unsigned int i = 0;i < N; ++i)

    {

    p->a[i] = i;

    }

    for (i = 0;i < N; ++i)

    {

    printf("%d\t",p->a[i]);

    }

    free(p);

    return 0;

    }

    首先定义结构体指针,然后进行动态内存的分配。之后是一个循环赋值,一个循环输出。奇怪的问题出现了,如果注释掉了free (p);运行一下,帅气的结果,如下图:

    psb (2)

    但是毕竟我们毕竟用到了动态内存分配时不是应该回收内存呢?所以去掉对free的注释,再次编译链接运行,一看,结果是没有错,只是多弹出了一个窗口,如下图:

    psb (1)

    这就奇怪了,既然能够将结果正确的输出,再结合前面能够“正确”输出,我们很容易确定是free出了问题,free(p)应该也是没有问题的,我们给它动态内存分配,现在回收肯定的没有问题的。难道是编译器的问题?

    应该不是编译器的问题吧,毕竟VC6.0十几年了依旧风光无限。再来检查检查??

    稍微仔细一点的同学都能发现p = (struct A*)malloc(sizeof(struct A*));是不是看起来有点别扭?解释解释?首先malloc函数申请一块sizeof(struct A*)这么大的内存,然后将返回类型强制转换为struct A型的指针赋值给p。那么sizeof(struct A*)是多大呢?熟悉指针的人都知道一般是4个字节,实在不知道的话,进入调试状态在watch窗口输入sizeof(p),因为p为struct A*,其大小即struct A*大小。

    问题已经非常明显了,我们要动态开辟一个struct A型的p,那么开创的空间肯定要和struct A一样大的,4字节够了吗?原来是多了一个*。更正以后运行,正确无误了。

    问题是比较简单的,也是非常容易解决的。但是,如果你忘记了free(不会报任何错误),而且你有将动态分配的p进行了很多其他的操作的时候,或者是在其他地方也动态开辟了内存的话。那么你会发现怎么这些数据都非常的奇怪,居然是凭空产生的,非常难以理解。明明是整个的思路,逻辑,语法都没错却有这样奇怪的结果。再回到前面的问题,我们只给p分配了4个字节,那么他是怎么访问结构体里面的100个int型的数据呢?这就不的不提起数组越界了。C是不对越界进行检查的,所以p中就如上面所提到的正确访问,正确赋值,正确输出。但是它访问的并不是它所拥有的空间,也就是其他变量的,如果其他变量进行其他操作的话,它的值也就变了。至于怎么变就不知道了。

    至于笔者所遇见的就更为奇特了。其他的地方都是没有错误的,甚至调试的时候也是没有错误的,输出结果完全正确,只是一旦点了VC上面的执行的时候,输出结果出现了几个非常奇怪的数。之后在command line下运行也是没有问题的。

    非常非常的奇怪。

    总而言之,malloc还是不用比较好,尽管我们只给p分配了4个字节但是它给我们的反馈是:

    psb

    其实从这也能够看出一些端倪,就不在细说了。建议是使用new代替malloc,alloc等。

    不要忘记回收内存。

    原作于2012年9月15日

    www.kingreturns.com
  • 相关阅读:
    创建你的 /proc 文件
    在 /proc 里实现文件
    使用 /proc 文件系统
    printk函数速率限制
    printk函数打开和关闭消息
    printk 函数消息是如何记录的
    mysql存储程序
    Javascript 笔记与总结(1-1)作用域
    Java实现 LeetCode 142 环形链表 II(二)
    Java实现 LeetCode 142 环形链表 II(二)
  • 原文地址:https://www.cnblogs.com/ashboy/p/2867143.html
Copyright © 2011-2022 走看看