好吧,也许我正在做一些致命的傻事,但我很生气.整天我一直在处理向我们自己的类中存储指针的向量,但是它们(大部分时间)都搞乱了.有时当我遍历它们时,我最终得到另一个向量的变量,有时我从内存中得到一些完全无意义的东西.
这是一些代码:
vectorclients; vector robots; //this function gets names from "robots" and sends them to all the "clients" void sendRobotListToClients(){ //collect the list: int numRobots = robots.size(); char *list = (char*)malloc(numRobots * USERNAME_SIZE); for(int i=0; i name); memcpy(&list[i*USERNAME_SIZE], robots[i]->name, namelen); if(namelen < USERNAME_SIZE) list[i*USERNAME_SIZE + namelen] = (char)0; } //send it to all clients: int numClients = clients.size(); for(int i=0; i sendRobotList(list, numRobots); if(result < 0){ cout<<"Failed sending refreshed list to " < name<<"."< clients; vector robots; //and this is how I add to them: robots.push_back(robot);
基本上,我没有得到我想要的记忆.我正在考虑去阵列,或者自己上课,但我想要动态存储.这很愚蠢,但......
robots.push_back(robot1); clients.push_back(client1);
举个例子:
TCPClientProtocol *robot = new TCPClientProtocol(mySocket); //create with existing socket robot->name = "robot1"; cout<name< name< TCPClientProtocols是从侦听服务器套接字派生的,该套接字返回套接字并将它们放入类中.当指针位于向量内部时,我在类中使用套接字函数,即
robot->sendData(buffer, lenght); robot->receiveData(buffer, length);之后,我再次尝试引用它们.我不能把所有的代码放在这里......它超过500行.
然后我收集机器人的名字,我要么得到gibbrish,要么得到客户的名字.无论如何,谢谢你的帮助.
编辑:我故意测试它,看看它在每一步到底做了什么.它打印出我想要的确切名称/字符串(机器人 - >名称).然而,在它被推入向量之后,我从向量中取出了完全相同的指针,它不再指向正确的名称,而是完全给了我别的东西.这就是为什么我很困惑.当没有涉及向量时,我显然很糟糕的记忆操作效果很好.
直接添加到向量的函数:
void addRobotToList(TCPClientProtocol *robot){ //add robot to list robots.push_back(robot); cout<<"Added "<name< 调用此函数的函数(警告:很长!) - 是的,我的意思是将其分开,但这是一种草稿:
DWORD WINAPI AcceptThread(void* parameter){ TCPClientProtocol* cl = (TCPClientProtocol*)parameter; TCPHeader *head = new TCPHeader; loginInfo *logInfo = new loginInfo; //Read header. int result = cl->receiveHeader(head); if(result < 0) return -1; //Check data. Expected: DATATYPE_CONNETION_REQUEST // and check protocol version. if( head->version != (char)PROTOCOL_VERSION || head->type != (char)DATATYPE_CONNECTION_REQUEST || head->size != (int)CONNECTION_REQUEST_LENGTH){ goto REJECT; } cout<<"Accepted connection."<requestLoginInfo(); if(result < 0) goto CONNECTIONLOST; //Read header. result = cl->receiveHeader(head); if(result < 0) goto CONNECTIONLOST; if(head->type != DATATYPE_LOGIN_INFO){ goto REJECT; } //read login information result = cl->receiveLoginInfo(logInfo); if(result < 0) goto CONNECTIONLOST; //check for authentication of connector. If failed, return. if(!authenticate(logInfo)){ goto REJECT; } cout<<"Authenticated."< name = logInfo->username; //Check for appropriate userType and add it as a variable: switch(logInfo->userType){ case USERTYPE_ROBOT: cl->userType = USERTYPE_ROBOT; cl->isClient = false; cout<<"Robot connected: "< name< userType = USERTYPE_CLIENT; cl->isClient = true; cout<<"Client connected: "< name< notifyPhaseChange(2); if(result < 0) goto CONNECTIONLOST; //if client, send robot availability list and listen for errors // and disconnects while updating client with refreshed lists. if(cl->isClient){ //add client to clients list: clients.push_back(cl); //send initial list: int numRobots = robots.size(); char *list = (char*)malloc(numRobots * USERNAME_SIZE); for(int i=0; i name< name); memcpy(&list[i*USERNAME_SIZE], robots[i]->name, namelen); if(namelen < USERNAME_SIZE) list[i*USERNAME_SIZE + namelen] = (char)0; } result = cl->sendRobotList(list, numRobots); if(result < 0){ removeClientFromList(cl->name); goto CONNECTIONLOST; } cout<<"Sent first robot list."< receiveHeader(head); if(result < 0){ removeClientFromList(cl->name); goto CONNECTIONLOST; } if(head->type != DATATYPE_ROBOT_SELECTION){ removeClientFromList(cl->name); goto REJECT; } //receive and process robot selection char *robotID = (char*)malloc(ROBOT_SELECTION_LENGTH+1); result = cl->receiveRobotSelection(robotID); robotID[USERNAME_SIZE] = (char)0; robotID = formatUsername(robotID); if(result < 0){ removeClientFromList(cl->name); goto CONNECTIONLOST; } cout<<"Got a selection.."< tcpConnected()){ //TRY AGAIN cout<<"Oh mai gawsh, robot DISCONNECTED!"< name< requestStreamSocketInfo(); if(result < 0){ removeClientFromList(cl->name); addRobotToList(robot); //re-add the robot to availability goto CONNECTIONLOST; } result = cl->receiveHeader(head); if(result < 0){ removeClientFromList(cl->name); addRobotToList(robot); //re-add the robot to availability goto CONNECTIONLOST; } //check for datatype if(head->type != DATATYPE_STREAM_SOCKET_INFO){ removeClientFromList(cl->name); addRobotToList(robot); //re-add the robot to availability goto REJECT; } //receive stream socket info: char *ip = (char*)malloc(20); int port; result = cl->receiveStreamSocketInfo(ip, &port); if(result < 0){ removeClientFromList(cl->name); addRobotToList(robot); //re-add the robot to availability goto CONNECTIONLOST; } cout<<"Got ip: "< sendStreamSocketInfo(ip, port); if(result < 0){ //RETURN CLIENT TO 'step 5' removeClientFromList(cl->name); delete robot; goto CONNECTIONLOST; } //send phase changes to both, and use this thread // to monitor signals from client to robot. result = cl->notifyPhaseChange(3); if(result < 0){ addRobotToList(robot); //re-add the robot to availability removeClientFromList(cl->name); goto CONNECTIONLOST; } result = robot->notifyPhaseChange(3); if(result < 0){ //RETURN CLIENT TO 'step 5' removeClientFromList(cl->name); delete robot; goto CONNECTIONLOST; } cout<<"PHASE 3 INITIATED"< name); //run a thread sending connections from CLIENT to ROBOT. while(true){ cout<<"Listening for header..."< receiveHeader(head); cout<<"Got something"< type != DATATYPE_COMMAND){ cout<<"Not a command. Protocol mismatch"< receiveCommand(); if(result < 0){ //RESET ROBOT! delete robot; goto CONNECTIONLOST; } cout<<"Got data."< sendCommand((char)result); if(result < 0){ //RESET CLIENT! delete robot; goto CONNECTIONLOST; } } //spawn a thread for robot-to-client and client-to-robot comm, // possibly just client-to-robot. //send a phase change (to phase 3) - in thread! } //if robot, add to robot list and wait. else{ //add robot to robots list: addRobotToList(cl); } delete head; delete logInfo; return 0; //Clean up variables and send reject message REJECT: cout<<"Connection rejected."< sendRejection(); delete cl; delete head; delete logInfo; return -1; CONNECTIONLOST: cout<<"Connection lost."<
john.. 5
您的代码是C和C++的可怕组合,当然所有错误都在C部分:).因此,不要责怪向量,而是看看所有可怕的低级内存操作.
在我看来
不能保证你不会溢出列表的界限
无法保证列表将被终止
列表内存泄漏
开始使用std :: string似乎是最好的建议.
1> john..:您的代码是C和C++的可怕组合,当然所有错误都在C部分:).因此,不要责怪向量,而是看看所有可怕的低级内存操作.
在我看来
不能保证你不会溢出列表的界限
无法保证列表将被终止
列表内存泄漏
开始使用std :: string似乎是最好的建议.
@Richard,没理由不使用字符串.只需在发送/接收字符串的位置转换为char数组(或char的向量).直接内存操作很难,你不是第一个错误的程序员,这就是为什么**我们有矢量,字符串等.