功能退出时出现问题 [英] having issue on exit of the function

查看:63
本文介绍了功能退出时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我是C ++的新手,在此位置退出"mlock.c"文件的功能后,我的代码崩溃了:

Hi,
I am quite new to C++ and I my code crashes after exiting the function in this place of "mlock.c" file:

void __cdecl _unlock (
        int locknum
        )
{
        /*
         * leave the critical section.
         */
        LeaveCriticalSection( _locktable[locknum].lock );
}



我的函数看起来像这样,应该返回false:



My function looks like this and should return false:

bool cCardClientNewCamd::SendMessage(const unsigned char *data, int len, bool UseMsgId, const struct CustomData *cd, comm_type_t commType)
{
  ...........
  return true;// cCardClientNewCamd::SendMsg(netbuf,len);
}

bool cCardClientNewCamd::CmdSend( net_msg_type_t cmd, comm_type_t commType)
{
  unsigned char buffer[3];
  buffer[0] = cmd; buffer[1] = buffer[2] = 0;
  return SendMessage(buffer,sizeof(buffer),false,0,commType);
}

int cCardClientNewCamd::CmdReceive( comm_type_t commType)
{
  unsigned char buffer[CWS_NETMSGSIZE];
  if(ReceiveMessage(buffer,false,0,commType)!=3) return -1;
  return buffer[0];
}

bool cCardClientNewCamd::SendMessage(const unsigned char *data, int len, bool UseMsgId, const struct CustomData *cd, comm_type_t commType)
{
  ......
  return true;// cCardClientNewCamd::SendMsg(netbuf,len);
}

int cCardClientNewCamd::ReceiveMessage(unsigned char *data, bool UseMsgId, struct CustomData *cd, comm_type_t commType)
{
  unsigned char netbuf[CWS_NETMSGSIZE];
  .......
  return returnLen;
}


bool cCardClientNewCamd::str2char(unsigned char *data,int *len,bool f, std::string s) 
{
	std::istringstream iss(s);
	unsigned char buf[240];
	int c=0;
	do
    {
		std::string sub;
        iss >> sub;
		int val= 0;
		sscanf(sub.c_str(), "%2x", &val);
		buf[c]=val;
		c++;
		//std::cout << "Substring: " << sub << std::endl;
    } while (iss);

	if (f)
	{
		*len = 2;
		memcpy (data,buf,2);
	}else{
		*len =(int) buf[1];
		memcpy (data,buf+2,*len);
	}
  return true;
}

int cCardClientNewCamd::RecvMsg(unsigned char *data, int id, bool f)
{
	int len=0;

	if (id==0)//SVR: Random data
		str2char(data,&len,f,(f?"0 E":"DE 75 27 A0 72 AB 83 72 F2 7D 34 3C AC 36"));

	return len;
}


// Failing to return function
bool cCardClientNewCamd::Login(void)
{
       unsigned char randData[14];
        int len=cCardClientNewCamd::RecvMsg(randData,0,false); //<-AFTER THIS CALL FAILS TO RETURN
	return false; //<- FAILS AFTER
	//....//
  	if(!SendMessage(buffer,buffer[2]+3,true,&cd) || CmdReceive()!=MSG_CLIENT_2_SERVER_LOGIN_ACK) {

		if(NextProto()) return Login();    
		return false;    
	}
	//...//
	return true;
}



调用此代码:



Code calling this:

int _tmain(int argc, _TCHAR* argv[])
{
	cCardClientNewCamd *cc = new cCardClientNewCamd("525");
	if (cc->Login() == true) // <- NEVER COMES OUT HERE
	{
		unsigned char data[240];//CWS_NETMSGSIZE];
		CustomData cd;
	}
	int hr=0;	
	printf("\n");
	system("pause");
	return 0;
}



标头说明:



header descriptions:

class cCardClientNewCamd :  private cTripleDes {
private:
  //cNetSocket so;
  unsigned char configKey[14];
  unsigned short netMsgId;
  int caId, protoVers, cdLen;
  bool emmProcessing;
  char username[USERLEN], password[PASSWDLEN];
  void InitVars(void);
  void InitProtoVers(int vers);
  bool NextProto(void);
  void InitCustomData(struct CustomData *cd, const unsigned short PrgId, const unsigned char *data);
  void PrepareLoginKey(unsigned char *deskey, const unsigned char *rkey, const unsigned char *ckey);

protected:
	int cCardClientNewCamd::RecvMsg(unsigned char *data, int id, bool f);
	bool cCardClientNewCamd::str2char(unsigned char *data,int *len,bool f, std::string s);
	void cCardClientNewCamd::prn(std::string txt, unsigned char *a, int nLen);
public:
  cCardClientNewCamd(const char *Name);
  virtual bool Login(void);
  // Client Helper functions
  bool SendMessage(const unsigned char *data, int len, bool UseMsgId, const struct CustomData *cd=0, comm_type_t commType=COMMTYPE_CLIENT);
  int ReceiveMessage(unsigned char *data, bool UseMsgId, struct CustomData *cd=0, comm_type_t commType=COMMTYPE_CLIENT);
  int cCardClientNewCamd::ReceiveMessage(unsigned char *data, bool UseMsgId, struct CustomData *cd, std::string txt, int id, comm_type_t commType=COMMTYPE_CLIENT);
  bool CmdSend( net_msg_type_t cmd,  comm_type_t commType=COMMTYPE_CLIENT);
  int CmdReceive( comm_type_t commType=COMMTYPE_CLIENT);



谁能解释为什么这行不通?

注意:缩小导致错误的位置,以便在返回崩溃后返回(行"int len = cCardClientNewCamd :: RecvMsg(randData,0,false);")),但不确定是什么问题.现在,在删除线程类代码后,它在其他地方崩溃:获得一个消息框,显示当前位置无源代码".



Could anyone explain why this does not work?

Note: Narrowed down where causes fault so after return crashes (line "int len=cCardClientNewCamd::RecvMsg(randData,0,false);") but not sure what is the problem. Now after removing thread class code crashes somewhere else: get a message box with "No Source Code Available for the Current Location".

推荐答案

简短答案是:请勿使用多线程/多处理或任何相关内容.并行和同步引发的问题甚至引起专家的头痛,而且某些方面根本没有干净的解决方案.这就是C ++标准委员会成员自己得出的结论! (这就是为什么标准C ++中很少支持多线程的原因)

如果您确实希望解决问题,我们将需要比这更多的信息,例如G.您如何管理线程,尤其是使用哪种类型的线程库;谁锁定什么,何时锁定以及为什么锁定;您应该在上面的代码中访问的各种变量应包含的内容,等等.甚至还不够.

到目前为止,我认为我可以从您的代码中收集到的唯一有用的信息是您调用了SendMessage,该名称可能已经引用了Windows函数.但是,SendMessage(Windows函数)需要一个窗口句柄作为它的第一个参数,因此您可能会错误地调用它,或者您可能正在调用自己的完全不同的函数,因此我们没有任何信息关于该功能的作用.
The short answer is: don''t use multithreading/multiprocessing, or anything related. The problems invoked by parallelism and synchronization cause splitting headaches even to experts, and there are certain aspects that simply have no clean solutions. And that is the conclusion even the members of the C++ Standards committee themselves came to! (which is the reason why there is so little support for multi-threading in standard C++)

If you really want your problem solved we''ll need a lot more information than this, e. g. how you manage your threads and especially what kind of threading library you are using; who locks what and when and why; what the various variables you access in the code above are supposed to hold, etc.. And even that may not be enough.

So far the only useful piece of information I thought I could gather from your code was that you call SendMessage which might have referred to the Windows function by that name. However, SendMessage (the Windows function) expects a window handle as it''s first parameter, so either you''re calling it wrong, or you may be calling an entirely different function of your own instead, and we have no information whatsoever about what that function does.


我将其发布在单独的解决方案中,因为我的其他解决方案是在没有用新的C ++程序员解释多线程问题的前提下发布的. .

这只是您与str2char有关的问题.我已将注释添加为注释,并在下面进行了解释:
I''m posting this in a separate solution because my other solution was posted under the premise that there is no use explaining problems of multithreading to a new C++ programmer.

This is just about your problem with str2char. I''ve added notes as comments and explained them below:
bool cCardClientNewCamd::str2char(unsigned char *data,int *len,bool f, std::string s) 
{
   std::istringstream iss(s);
   unsigned char buf[240];                  // 1
   int c=0;
   do
   {
      std::string sub;
      iss >> sub;                           // 2
      int val= 0;
      sscanf(sub.c_str(), "%2x", &val);
      buf[c]=val;                           // 3
      c++;                                  // 4
   } while (iss);                           // 5
 
   if (f)
   {
      // ...
   }else{
      *len =(int) buf[1];                   // 6
      memcpy (data,buf+2,*len);             // 7
   }
   return true;
}


1)您声明了一个缓冲区而没有对其进行初始化.这不一定是问题,但是...请参见下文

2)您从stringstream中读取了string类型的变量sub,这意味着全部!空格是有效字符,并且是该字符串的一部分,而不是您期望的分隔符.

3)至少在第一次分配buf [0]时,它应该可以按预期工作.我不太确定下一次-是否有(见下文)

4)c将会增加...一次,就我所能说的(见下文)

5)我不知道从strstream到bool有转换功能吗?通常,您应该使用operator!()或成员函数good()或bad()或eof()来测试strstream的状态!即使您的编译器没有抱怨,这可能也值得解决.但是请看下面...

无论如何,有两种可能性:要么您的条件永远不会为真,并且您的循环将无限运行,要么此时它立即终止(因为已经读取了全部内容),从而导致上述问题,并在下面进行说明.

6)buf [1]尚未初始化,因此您正在复制未定义的值!

7)buf + 2仅包含更多未初始化的内存-但这并不重要,因为您正在尝试复制长度不确定的数据块(请参见6).


我的建议
现在忘记strstream和字符串,并使用标准C重写该函数-只需在该字符串字符之间迭代,以便您知道自己在做什么.一旦运行正常,您应该总是可以尝试使用C ++类,但是如果这样做,请不要将其与sscanf这样的C样式函数混合使用-只是在自找麻烦.


1) you declared a buffer without initializing it. This isn''t necessarily a problem, but... see below

2) You read the variable sub of type string from a stringstream - which means all of it! Spaces are valid characters and as such part of that string, not a separator as you might have expected.

3) This should work as intended, at least the first time, when you assign buf[0]. I''m not so sure about the next times - if there are any (see below)

4) c will be incremented ... once, for all I can say (see below)

5) I''m not aware there is a conversion function from strstream to bool? Normally you should use operator!() or the member functions good() or bad() or eof() to test the state of the strstream!? Even if your compiler didn''t complain, this might be worth fixing. But see below...

In any case, there''s two possibilities: either your condition will never be true and your loop will run infinitely, or it terminates immediately at this point (since the entire contents have been read out already), leading to the problems indicated above, and described below.

6) buf[1] has never been initialized, so you''re copying an undefined value!

7) buf+2 contains just more uninitialized memory - but it doesn''t really matter because you''re trying to copy a data block of undetermined length (see 6).


My advice
Forget strstream and string for now and rewrite that function with standard C - just iterate over that string character for character so you know what you''re doing. Once it works like it should you can always come back and try your luck with C++ classes, but if you do, try to not mix that with C style functions such as sscanf - that''s just asking for trouble.


终于找到了它,在第7行中复制内存的字符串长度是错误的(比想象的要大得多).

解决此问题解决了我的问题:
Found it at last, the length of string to copy memory in line 7 was incorect (much bigger than supposed to be).

Fixing to this resolved my issue:
bool cCardClientNewCamd::str2char(unsigned char *data,int *len,bool f, std::string s) 
{
	std::istringstream iss(s);
	unsigned char buf[240];
	int c=0;
	do
    {
		std::string sub;
        iss >> sub;
		int val= 0;
		sscanf(sub.c_str(), "%2x", &val);
		buf[c]=val;
		c++;
    } while (iss);

	if (f)
	{
		*len = 2;
		memcpy (data,buf,2);
	}else{
		*len =(int) buf[1];
		memcpy (data,buf+2,(size_t) *len);
	}
  return true;
}

int cCardClientNewCamd::RecvMsg(unsigned char *data, int id, bool f)
{
	int len=0;

	if (id==0)//SVR: Random data
		str2char(data,&len,f,"0 E DE 75 27 A0 72 AB 83 72 F2 7D 34 3C AC 36");
	
	return len;
}



感谢您的支持.



Thanks for support.


这篇关于功能退出时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆