c++ - Valgrind - 未初始化的值和字节?

标签 c++ tcp byte valgrind initialization

Valgrind 给我错误提示 -

Syscall param write(buf) points to uninitialised byte(s)

Conditional jump or move depends on uninitialised value(s)

我不知道如何解决这个问题。所有的错误都在同一个地方。我有一个 tcp 服务器与其客户端通信的功能。如果它从任何客户端接收到消息,它会将消息传递给另一个函数。当我调用这个函数时,所有的错误都会发生。不幸的是,Valgrind 没有给我函数的行号,它只是说

by 0x805683F: TcpServer::getSendBack(char*, char) (basic_string.h:2503).

其中一个的整个错误消息是 -

==8759== 1 errors in context 1 of 5:
==8759== Syscall param write(buf) points to uninitialised byte(s)
==8759==    at 0x446CFDB: ??? (syscall-template.S:82)
==8759==    by 0x4416B3E: new_do_write (fileops.c:530)
==8759==    by 0x4416E55: _IO_do_write@@GLIBC_2.1 (fileops.c:503)
==8759==    by 0x441793C: _IO_file_overflow@@GLIBC_2.1 (fileops.c:881)
==8759==    by 0x4416C87: _IO_file_xsputn@@GLIBC_2.1 (fileops.c:1358)
==8759==    by 0x440CA9D: fwrite (iofwrite.c:45)
==8759==    by 0x4300DE5: __gnu_cxx::stdio_sync_filebuf<char, std::char_traits<char>     >::xsputn(char const*, int) (in /usr/lib/libstdc++.so.6.0.13)
==8759==    by 0x4303691: std::basic_ostream<char, std::char_traits<char> >&     std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char,     std::char_traits<char> >&, char const*, int) (in /usr/lib/libstdc++.so.6.0.13)
==8759==    by 0x8056825: TcpServer::getSendBack(char*, char) (ostream:510)
==8759==    by 0x805729C: TcpServer::communicate() (tcpserver.cpp:369)
==8759==    by 0x805B7B1: ServerControl::control() (servercontrol.cpp:173)
==8759==    by 0x804FE6E: main (main.cpp:230)
==8759==  Address 0x4028110 is not stack'd, malloc'd or (recently) free'd
==8759==  Uninitialised value was created by a stack allocation
==8759==    at 0x8056FA6: TcpServer::communicate() (tcpserver.cpp:304)

还有一个错误——

==8759== 1 errors in context 2 of 5:
==8759== Conditional jump or move depends on uninitialised value(s)
==8759==    at 0x4416D8C: _IO_file_xsputn@@GLIBC_2.1 (fileops.c:1317)
==8759==    by 0x440CA9D: fwrite (iofwrite.c:45)
==8759==    by 0x4300DE5: __gnu_cxx::stdio_sync_filebuf<char, std::char_traits<char> >::xsputn(char const*, int) (in /usr/lib/libstdc++.so.6.0.13)
==8759==    by 0x4303691: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, int) (in /usr/lib/libstdc++.so.6.0.13)
==8759==    by 0x805683F: TcpServer::getSendBack(char*, char) (basic_string.h:2503)
==8759==    by 0x805729C: TcpServer::communicate() (tcpserver.cpp:369)
==8759==    by 0x805B7B1: ServerControl::control() (servercontrol.cpp:173)
==8759==    by 0x804FE6E: main (main.cpp:230)
==8759==  Uninitialised value was created by a stack allocation
==8759==    at 0x8056FA6: TcpServer::communicate() (tcpserver.cpp:304)

main 230 只是对 servercontrol 中控制函数的调用,servercontrol 173 只是 pthread_create 调用。

如果有人能帮我弄清楚为什么会出现这些错误,我将不胜感激。通信功能是 -

void TcpServer::communicate() {


fd_set read_flags, write_flags; // the flag sets to be used
int sel;        // holds return value for select();
int numRead = 0;    //holds return value for read()
int numSent = 0;    //holds return value for send()
char in[255];   //in buffer for client 1
char out[512];  //out buffer

//clear buffers
memset(&in, 0, 255);
memset(&out, 0, 512);

int nfds = 0;
for(int i=0;i<count;i++)
    nfds += clients[i].fd;

while(!done) {
    //reset the fd_sets
    FD_ZERO(&read_flags);
    FD_ZERO(&write_flags);
    FD_SET(STDIN_FILENO, &read_flags);
    FD_SET(STDIN_FILENO, &write_flags);

    //put fds back in
    for(int i=0;i<count;i++) {
        FD_SET(clients[i].fd, &read_flags);
        FD_SET(clients[i].fd, &write_flags);
    }   //end for

    //call select
    sel = select(nfds+1, &read_flags, &write_flags, (fd_set*)0, 0);

    //if an error with select
    if(sel < 0)
        continue;

    //loop through clients
    for(int i=0;i<count;i++) {
        //check if ready for reading
        if(FD_ISSET(clients[i].fd, &read_flags)) {

            //clear set
            FD_CLR(clients[i].fd, &read_flags);
            //clear in
            memset(&in, 0, 255);

            numRead = recv(clients[i].fd, in, 255, 0);
            if(numRead < 0) {
                printf("\nError reading from Client 1: %m", errno);
                clients[i].agent->getRobot()->pauseSensorStream();
                done = true;
            }   //end if error
            //if connection closed, exit
            else if(numRead == 0) {
                printf("\nClosing socket");
                close(clients[i].fd);
                done = true;
                i = count;
            }   //end if connection closed
            //if message, call getsendback
            else if(in[0] != '\0') {
                if(read_mess)
                    std::cout<<"\nMessage successfully received from Client "<<clients[i].id<<": "<<in;
                getSendBack(in, clients[i].id);
            }   //end if message
        }   //end if
    }   //end for



    /*CHECK FOR STDIN*/

    //if stdin is ready for reading
    if(FD_ISSET(STDIN_FILENO, &read_flags)) {
        fgets(out, 512, stdin);

        //if changing the view
        if(out[0] == 'v') {
            std::string temp(out);
            char w = temp.substr(2, 1)[0];
            which_display = w;
        }   //end if changing the view

        //else check for writing
        else {

            for(int i=0;i<count;i++) {
                //if a socket is reading for writing
                if(FD_ISSET(clients[i].fd, &write_flags)) {

                    //clear set
                    FD_CLR(clients[i].fd, &write_flags);

                    //if not changing the view and begins with a digit or quitting
                    if(is_id(out[0]) || out[0] == 'q') {

                        //create message to send
                        std::stringstream tosend;

                        //if not the quit command
                        if(out[0] != 'q') {

                            //make a temp of out to substr out the client id
                            std::string temp(out);
                            tosend<<"@ "<<temp.substr(2, temp.length() - 2);
                            //std::cout<<"\ntosend: "<<tosend.str();

                            //send message to the client
                            numSent = send(get_client_fd(out[0]), tosend.str().c_str(), tosend.str().length(), 0);

                        }   //end if not the quit command

                        //if quit command
                        else {

                            tosend<<"@ q";
                            //std::cout<<"\ntosend: "<<tosend.str();

                            //send message to quit to all clients
                            for(int i=0;i<count;i++)
                                numSent = send(clients[i].fd, tosend.str().c_str(), tosend.str().length(), 0);

                        }   //end quit message

                        //if error, exit
                        if(numSent < 0) {
                            printf("\nError sending to Client %c\nMessage: %s\nError message %m", out[0], out, errno);
                            done = true;
                            i = count;
                        }   //end if error

                        //if no error and sent_mess is true, print message
                        else if(numSent > 0 && sent_mess)
                            std::cout<<"\nMessage successfully sent to Client "<<out[0]<<": "<<tosend.str();

                    }   //end if not changing view and begins with a digit or quitting

                    //wait for message to get there, then clear
                    usleep(10000);
                    memset(&out, 0, 512);
                }   //end if
            }   //end for
        }   //end if not changing view
    }   //end if stdin ready for reading
}   //end while
}   //END COMMUNICATE

我认为问题出在 getSendBack 的最开始 -

void TcpServer::getSendBack(char* command, char client_id) {
std::string tempCommand(command);
//std::cout<<"\ntempCommand: "<<tempCommand;

//count the number of headers
int num_headers = 0;
for(int i=0;i<tempCommand.length() && num_headers < 2;i++)
    if(tempCommand[i] == '@')
        num_headers++;

//if no message stacking
if(num_headers == 1) {

    //if packet id 1 (update pos/goal/direction)
    if(tempCommand[2] == '1') {

        //get position row
        int prowend = 4;
        while(isdigit(tempCommand[prowend]))
            prowend++;
        std::string p(tempCommand.substr(4, prowend-3));
        int prow = atoi(p.c_str());
        //std::cout<<"\nprow: "<<prow;

        //get position column
        int pcolend = prowend+1;
        while(isdigit(tempCommand[pcolend]))
            pcolend++;
        std::string c(tempCommand.substr(prowend, pcolend-prowend));
        int pcol = atoi(c.c_str());
        //std::cout<<"\npcol: "<<pcol;

        //get goal row
        int growend = pcolend+1;
        while(isdigit(tempCommand[growend]))
            growend++;
        std::string gr(tempCommand.substr(pcolend, growend-pcolend));
        int grow = atoi(gr.c_str());
        //std::cout<<"\ngrow: "<<grow;

        //get goal column
        int gcolend = growend+1;
        while(isdigit(tempCommand[gcolend]))
            gcolend++;
        std::string gc(tempCommand.substr(growend, gcolend-growend));
        int gcol = atoi(gc.c_str());
        //std::cout<<"\ngcol: "<<gcol;

        char direction = tempCommand[tempCommand.length()-1];
        //std::cout<<"\ndirection: "<<direction;


        Position temp_pos(prow, pcol);
        Position temp_goal(grow, gcol);

        //lock
        pthread_mutex_lock(&mutex_agent);

        //set the new information for the client
        get_client(client_id).agent->setPosition(temp_pos);
        get_client(client_id).agent->setGoal(temp_goal);
        get_client(client_id).agent->setDirection(direction);

        //unlock
        pthread_mutex_unlock(&mutex_agent);
    }   //end if new goal


    //else if packet id 2 (change sensor)
    else if(tempCommand[2] == '2') {
        int idend = 4;
        while(isdigit(tempCommand[idend]))
            idend++;
        std::string temp(tempCommand.substr(4, idend-2));

        //std::cout<<"\ntemp: "<<temp;
        int id = atoi(temp.c_str());

        //if valid id value, set new current sensor
        if(id > 6 && id < 43)
            get_client(client_id).agent->getRobot()->setCurrentSensor(id);
        else
            std::cout<<"\n"<<id<<" is Invalid id";
    }   //end if new sensor

    //else if 5, quit
    else if(tempCommand[2] == '5')
        done = true;

}   //end if 1 header
//else if stacking
else
    std::cout<<"\nSTACKED MESSAGE: "<<tempCommand;
}   //END GETSENDBACK

最佳答案

什么是:“main.cpp:230”、tcp server.cpp:304? 他们似乎是问题所在

关于c++ - Valgrind - 未初始化的值和字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7681070/

相关文章:

java - 接口(interface)、协议(protocol)和抽象类

c++ - 类和成员函数(初学者)

http - 什么控制 TCP 段是传递到传递给 accept() 的套接字还是传递给 accept() 返回的套接字?

c++ - 当它只有 4 个字节时,float 怎么可能容纳 3.4E38 这样大的数字呢?

c++ - 为什么 "using namespace std;"被认为是不好的做法?

导入 dll 时的 c++ lnk 2028、lnk 2020、lnk2019 和 lnk2001

ruby - 通过 SO_RCVTIMEO 套接字选项在 Ruby 中设置套接字超时

c++ - 解析查询与使用 IP 和端口创建端点之间的区别(在 boost asio 中)

byte - 为什么1字节等于8位?

c++ - 在 C++ 中将字节写入 ofstream