今天关机下班时一同事说我的游戏登陆不了了,经过查看日志和代码逻辑分析,觉得我的程序没有问题。弄了十几分钟,还是没能解决问题。还好游戏还没有正式开服,索性我回家继续研究这个问题。经过验证后发现我的代码底层有问题,因为底层是我自己写的,所以。。。。。。好吧,就来说说这个问题吧。
我的问题出在申请内存后的初始化问题上。
首先来看下下面的代码:
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操作符,最好考虑到内存申请失败时的出来,我上面的做法是没有考虑内存申请失败时的处理。
很晚了,睡觉咯!
阅读(1209) | 评论(0) | 转发(0) |