Chinaunix首页 | 论坛 | 博客
  • 博客访问: 206161
  • 博文数量: 47
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1259
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-24 10:20
文章分类
文章存档

2014年(21)

2013年(26)

分类: 网络与安全

2014-01-02 17:55:00

今天关机下班时一同事说我的游戏登陆不了了,经过查看日志和代码逻辑分析,觉得我的程序没有问题。弄了十几分钟,还是没能解决问题。还好游戏还没有正式开服,索性我回家继续研究这个问题。经过验证后发现我的代码底层有问题,因为底层是我自己写的,所以。。。。。。好吧,就来说说这个问题吧。

   我的问题出在申请内存后的初始化问题上。

   首先来看下下面的代码:

   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    
#include
#include
#include "classnew.h"
class A
{
    public:
        A(){printf("A()\n");}
        virtual  ~A(){printf("~A()\n");}
};
class B
{
    public:
        B(){printf("B()\n");}
        virtual  ~B(){printf("~B()\n");}
};
class C : public A,B
{
    public:
        C():A(),B()
            {printf("C()\n");}
        virtual ~C(){printf("~C()\n");}
        int c;
};
int main()
{
    C*p = new C();
    p->c = 123456;
    printf("c0:%d\n",p->c);
    delete p;
    C*p1 = new C();
    printf("c1:%d\n",p1->c);
    delete p1;
    return 0;
}
这个程序的运行结果是:


A()
B()
C()
c0:123456
~C()
~B()
~A()
A()
B()
C()
c1:123456
~C()
~B()
~A()


我们不难看出,C1的打印结果居然跟c的打印结果一样,我已经重新申请内存了,为什么结果还一样呢?这就是问题所在,c++内存申请和初始化问题

后来我重写了new和delete操作符

代码如下:
1
2
3
4
5
6
7
8
9
10
    
void *operator new(size_t size)
{
    printf("new\n");
        return calloc(1, size);
}
void operator delete(void *p)
{
    printf("delete\n");
        return free(p);
}


加上以上的代码后,重新编译运行:

new
A()
B()
C()
c0:123456
~C()
~B()
~A()
delete
new
A()
B()
C()
c1:0
~C()
~B()
~A()
delete


这说明我的程序在申请内存是已经初始化了内存为0,到这里问题已经缩小。是new没有初始化还是delete后没有重置内存?

好,我再来把重载的new去掉,发现有出现第一种情况,存储没有被初始化为0;再把delete去掉没,发现还是出现内存没有初始化为0,所以我认为 clloc和free需要充实出现才会将内存初始化为0,这个跟系统有关,关于这对函数我想日后在去研究;

我再把new中的clloc改用malloc,结果还是跟第一种情况一样,内存没有被初始化为0;好,到这我们可以解决下半时出现的问题了,就是自己写的底层里面没有重载 new和delete操作符导致的,malloc和free组合的函数对没有对内存做初始化,而clloc和free组合的函数对会初始化申请的内存为0;

所以我的解决方案是重载new和delete操作符如下:
1
2
3
4
5
6
7
8
9
10
    
void *operator new(size_t size)
{
    printf("new\n");
        return calloc(1, size);
}
void operator delete(void *p)
{
    printf("delete\n");
        return free(p);
}

提醒:c++申请内存是最好重载new和delete操作符,最好考虑到内存申请失败时的出来,我上面的做法是没有考虑内存申请失败时的处理。

很晚了,睡觉咯!
阅读(1218) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~