none
单例模式导致的内错错乱问题 RRS feed

  • 问题

  • 先附上代码:

    /// <summary>
    /// 服务器配置类,此类请不要直接作用于Common文件夹里的任何文件,除过本身
    /// </summary>
    class ServerConfig
    {
    	SINGLE_MODEL(ServerConfig)
    
    public:
    	int				Initialize(const wchar_t* script_file_name);
    
    public:
    	const char*		ServerIp1(void) const{return (const char*)_c_d->_server_ip1.c_str();}
    	const char*		ServerIp2(void) const{return (const char*)_c_d->_server_ip2.c_str();}
    	unsigned int	Port1(void)const{return _c_d->_port1;}
    	unsigned int	Port2(void)const{return _c_d->_port2;}
    
    	unsigned int	PrepareAcceptSocketCount1(void)const{return _c_d->_prepare_accept_socket_count1;}
    	unsigned short  AcceptorWorkCount1(void)const{return _c_d->_acceptor_work_count1;}
    	unsigned short  AcceptorWorkCount2(void)const{return _c_d->_acceptor_work_count2;}
    
    
    	unsigned int	ReceiveBufferSize1(void)const{return _c_d->_receive_buffer_size1;}
    	unsigned int	SendBufferSize1(void)const{return _c_d->_send_buffer_size1;}
    	unsigned int	ReceiveBufferSize2(void)const{return _c_d->_receive_buffer_size2;}
    	unsigned int	SendBufferSize2(void)const{return _c_d->_send_buffer_size2;}
    
    
    	unsigned short	InfoTransferStationWorkThreadCount(void)const{return _c_d->_info_transfer_station_work_thread_count;}
    
    	const wchar_t*	DatabaseName()const{return _c_d->_database_name;}
    	const wchar_t*	DatabaseAccountName()const{return _c_d->_database_account_name;}
    	const wchar_t*	DatabaseAccountPwd()const{return _c_d->_database_account_pwd;}
    
    	unsigned int	DatabaseReceiveBufferSize()const {return _c_d->_database_receive_buffer_size;}
    	unsigned int	DatabaseWorkThreadCount()const{return _c_d->_database_work_thread_count;}
    
    private:
    	int				ReadConfigScript(const wchar_t* file_name);
    
    private:
    	_config_data* _c_d;
    };
    
    #define SVRCONFIG ServerConfig::GetInstance()

    上面代码省去了_config_data的定义,这是一个数据类对象。

    #define SINGLE_MODEL(_class)		public: \
    									~_class( void ); \
    									static _class* GetInstance(){return _instance == NULL ? (_instance = new _class()) : _instance;} \
    									private: \
    									_class( void ); \
    									static _class* _instance;
    


    以上是单例模式的定义。

    		ServerConfig* tmpSvrConfig = SVRCONFIG;
    
    		if(NETWORK2->Initialize((char*)tmpSvrConfig->ServerIp1(), tmpSvrConfig->Port1(), tmpSvrConfig->AcceptorWorkCount1(), tmpSvrConfig->ReceiveBufferSize1())){
    			ErrorPrint()(eEPCV_green, "gameprocess init successfully.");
    		}
    


    这里是对单利的调用。

    问题在于:

    ServerConfig* tmpSvrConfig = SVRCONFIG;


    通过以上代码,当通过SVRCONFIG获取到ServerConfig类对象的指针后,检查tmpSvrConfig->_c_d是正确的指针,内存以及值都是正确的。

    当通过

    tmpSvrConfig->ReceiveBufferSize1()

    这样的方式去获取值的时候,是错误的,跟踪到

    unsigned int	ReceiveBufferSize1(void)const{return _c_d->_receive_buffer_size1;}

    发现_c_d的指针跟/ServerConfig* tmpSvrConfig = SVRCONFIG;/的tmpSvrConfig->_c_d 指针值不一样,这就表明内存指针不对了,而且经过比较发现tmpSvrConfig的指针值也跟 【跟踪到

    unsigned int	ReceiveBufferSize1(void)const{return _c_d->_receive_buffer_size1;}

    】这里的this指针值不一致。

    这是为什么,实在想不明白。求大神指教...

    2014年6月16日 3:38

答案

  • 你好,搞定了,谢谢,还是自己犯的错误,,,哎,折腾了这么多天,

    原来是一个辅助函数初始化内存时,

    正确的应该是memset(wstr,0, wstrLen);

    之前写成了memset(wstr,0, sizeof(wchar_t)*wstrLen);

    ---

    抱歉...

    我现在怎么不能删除帖子了,,,,

    2014年6月20日 1:31

全部回复

  • 你好,

    据我所知,单例模式下的实例指针最好设为静态的,可以保证向其他对象提供唯一的同一个内存区的实例指针。同时你可以参考一下这个blog:

    http://www.nowamagic.net/librarys/veda/detail/1776

    另外,你可以提供一下你debug 的输出截屏来看看。

    May


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年6月17日 9:45
  • 你好,谢谢你的回答,

    单例模式下的实例指针最好设为静态的,这个我肯定是静态的,

    而且是在main函数里,主线程里初始化,这个时候还没有开其他线程,

    ----

    调试截图只能过几天,这个问题暂时绕过了,但是这应该不是办法,谢谢!!

    2014年6月19日 7:11
  • 你好,搞定了,谢谢,还是自己犯的错误,,,哎,折腾了这么多天,

    原来是一个辅助函数初始化内存时,

    正确的应该是memset(wstr,0, wstrLen);

    之前写成了memset(wstr,0, sizeof(wchar_t)*wstrLen);

    ---

    抱歉...

    我现在怎么不能删除帖子了,,,,

    2014年6月20日 1:31
  • 你好,

    非常高兴您的问题解决了,虽然不是单例模式的问题。根据这个问题的情况,我将您的solution标记为了答案以供其他人参考。

    May


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年6月20日 6:54