2011-09-05 127 views
0

我有一些可能的內存泄漏(根據valgrind)和無效讀取。我希望有人能夠幫助我理解他們爲什麼會發生。內存泄漏問題

首先我得到無效的讀取和跟蹤導致我把值放入一個stringstream。這裏是跟蹤 -

Thread 4: 
Invalid read of size 4 
    at 0x80586AB: TcpClient::updateServerAgent() (tcpclient.cpp:64) 
    by 0x805CB15: ClientControl::update_server_thread(void*) (clientcontrol.cpp:49) 
    by 0x4040E98: start_thread (pthread_create.c:304) 
    by 0x43C873D: clone (clone.S:130) 
    Address 0x4553290 is 24 bytes inside a block of size 52 free'd 
    at 0x4025907: operator delete(void*) (vg_replace_malloc.c:387) 
    by 0x804F0A0: main (main.cpp:191) 

我會發布這些代碼塊。 Main -

 //make agent and set robot's agent 
    Agent* agent = new Agent(g, robot, 'e'); 
    robot.setAgent(agent); 

    //make initial start and goal positions 
    Position start(1,1); 
    Position end(1,1); 
    agent->setPosition(start); 
    agent->setGoal(end); 

    //set initial path 
    //Position goal = agent->getGoal(); 
    Path p = agent->traverse(agent->getGoal()); 
    agent->setPath(p); 


    client.setIP(args[3]); 
    u_client.setIP(args[3]); 


    //launch the clients 
    if(client.launchClient() && u_client.launch_client()) { 


     cout<<"\nSuccessful Connection!"; 

     //set robot id 
     agent->getRobot()->setID(args[4][0]); 

     //set the agents 
     client.setAgent(agent); 
     u_client.setAgent(agent); 

     //set client control's members 
     cc.setClient(&client); 
     cc.setUDP(&u_client); 

     //go 
     cc.control(); 

     robot.pauseSensorStream(); 
     delete agent; //************LINE 191*************** 
    } //end if successful connection 
} //end if client 

ClientControl -

inline void ClientControl::update_server_thread_i() { 
for(;;) { 
    usleep(UPDATE_SERVER_TIME); 
    myClient->updateServerAgent(); //***********LINE 49************** 
} //end while 
} 

updateSeverAgent -

void TcpClient::updateServerAgent() { 

//hold message to get the length of it 
std::stringstream messagelength; 
//message is 1 prow pcol grow gcol sensorhigh sensorlow 

//************LINE 64 IS THE NEXT LINE OF MESSAGELENGTH<<...******************* 

messagelength<<"1 "<<myAgent->getPosition().getRow()<<" "<<myAgent->getPosition().getCol()<<" "<<myAgent->getGoal().getRow()<<" "<<myAgent->getGoal().getCol(); 
//make it into a string 
std::string tempStrLen = messagelength.str(); 


int length_of_rest = 3; 

//find number of digits in prow 
while(isdigit(tempStrLen[length_of_rest])) 
    length_of_rest++; 

//****repeat that process a few times** 

//create message to send to server 
std::stringstream message; 
message<<"@ "<<messagelength.str(); //*****note I don't get an issue here**** 

//std::cout<<"\nmessage: "<<message.str(); 

//send 
int numSent = send(fd, message.str().c_str(), message.str().length(), 0); 
} //END UPDATESERVERAGENT 

可能的泄漏我想不出有任何調用線程的回調或者是與做創建字符串流。我在每個線程上都可能發生泄漏,但我只會將信息發佈到一個。以下是跟蹤 -

22 Bytes in 1 blocks are possibly lost in loss record 3 of 12 
    at 0x402641D: operator new(unsigned int) (vg_replace_malloc.c:255) 
    by 0x42579F7: std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.14) 
    by 0x805880C: TcpClient::updateServerAgent() (basic_string.tcc:138) 
    by 0x805CB15: ClientControl::update_server_thread(void*) (clientcontrol.cpp:49) 
    by 0x4040E98: start_thread (pthread_create.c:304) 
    by 0x43C873T: clone (clone.S:130) 

updateServerAgent代碼位於第49行的上方。我看到跟蹤中的操作符是新的,但我從來沒有在我的updateServerAgent代碼中使用new關鍵字。如果需要,我可以發佈整個代碼。

另一條與start_thread和 之間相同的跡線只是不同的功能由0x42579F7: std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.14)

其是

by 0x805FD02: udpclient::communicate() (basic_string.tcc:138) 
by 0x805CAE3: ClientControl::udp_comm_thread(void*) (clientcontrol.cpp:62) 

該代碼是 -

inline void ClientControl::udp_comm_thread_i() { 
myUDP->communicate(); //*****LINE 62******* 
} 

-

void udpclient::communicate() { 

//message to send 
std::ostringstream tosend; 
//hold return value of sendto 
int numSent; 

while(1) { 

    //sleep 
    usleep(15000); 

    //reset tosend 
    tosend.str(""); 
    //grab sensor values 
    Sensor_Packet temp = myAgent->getRobot()->getSensorValue(myAgent->getRobot()->getCurrentSensor()); 

    //put header onto tosend and concatenate the values 
    tosend<<"@ "<<myAgent->getRobot()->getID()<<" "<<temp.values[1]<<" "<<temp.values[0]; 

    //send 
    numSent = sendto(fd, tosend.str().c_str(), tosend.str().length(), 0, servinfo->ai_addr, servinfo->ai_addrlen); 
    if(numSent < 0) 
     printf("\nError sending %m", errno); 
    //else 
     // cout<<"\nUDP Sent: "<<tosend.str(); 
} //end while 
} //END COMMUNICATE 

如果有人可以幫我弄清楚/瞭解這些可能的泄漏,我會非常感謝你。

+0

這是C嗎?將標記更改爲C++ – phoxis

+10

TL; DR .......... – 2011-09-05 17:38:22

+1

嘗試將第64行拆分爲多個流<< foo;報表,分開行。這應該給出一個線索,哪個論點給出警告。 –

回答

2

關於內存泄漏:我不會擔心太多。這只是一個可能的泄漏,我們也看到了有關字符串泄漏的報告,這是我們無法解釋的,但這並不會導致內存耗盡。

關於無效的讀取:顯然,在main()中刪除它之後仍然使用該代理。代理被傳遞給客戶,但客戶沒有注意到該代理被刪除;這可能會導致這類問題。

+0

謝謝你的幫助。你對無效閱讀是正確的。 – Sterling