当前位置:  开发笔记 > 编程语言 > 正文

C++(Windows)为什么向量会导致内存错误?

如何解决《C++(Windows)为什么向量会导致内存错误?》经验,为你挑选了1个好方法。

好吧,也许我正在做一些致命的傻事,但我很生气.整天我一直在处理向我们自己的类中存储指针的向量,但是它们(大部分时间)都搞乱了.有时当我遍历它们时,我最终得到另一个向量的变量,有时我从内存中得到一些完全无意义的东西.

这是一些代码:

vector clients;
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; iname);
        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; isendRobotList(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; iname<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的向量).直接内存操作很难,你不是第一个错误的程序员,这就是为什么**我们有矢量,字符串等.
推荐阅读
大大炮
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有