2015-02-02 2 views
0

두 개의 스레드를 포함하여, 다음 코드를하시기 바랍니다 고려 buffering_thread (하나의 메시지 버퍼 포인터를 채워)과 sending_thread 사이의 메모리 누수가 (버퍼를 비 웁니다)이 있습니까 :두 개의 스레드 (비우기 버퍼링)

#include "msg.cpp" 

msg * buffer= NULL; 
byte * send_bytes= NULL; 
bool keep_buffering = true; 
bool keep_sending = true; 
int counter = 0; 

void start_buffering() { 
    while (keep_buffering){ 
     while (buffer != NULL && keep_buffering){} 
     msg m (counter); 
     buffer = &m; 
     counter ++; 
    } 
    std::cout << "Finished start_buffering" << std::endl; 
} 

void sending() { 
    while (keep_sending){ 
     if (counter > 10){ 
      keep_buffering = false; 
      break; 
     } 
     if (buffer != NULL){ 
      HeaderType messageHeader = buffer -> getHeader(); 
      print(messageHeader); 
      send_bytes = (byte *) realloc(send_bytes,DATASIZE + HEADER); 
      memcpy (send_bytes, &messageHeader, HEADER); 
      memcpy (send_bytes + HEADER,buffer -> getText(), DATASIZE); 
      // Do something, suppose for now NOTHING 
      free (buffer -> getText()); 
      buffer = NULL; 
     } 
    } 
    std::cout << "Finished sending" << std::endl; 
} 

int main() { 

    std::thread sending_thread(sending); 

    std::thread buffering_thread(start_buffering); 

    buffering_thread.join(); 

    keep_sending = false; 

    sending_thread.join(); 

    //free (buffer); 
    free (send_bytes); 
    return 0; 
} 

#include <iostream> 
#include <stdlib.h> 
#include <cstring> 
#include <mutex> 
#include <thread> 
#define DATASIZE 10 
#define HEADER sizeof(HeaderType) 

class msg 
{ 
    private: 
     HeaderType header; 
     byte * text;  

    public: 
     msg(int ID); 
     HeaderType getHeader(); 
     byte * getText(); 
}; 

msg::msg(int ID){ 
    header.mID = ID; 
    text = (byte *)malloc (DATASIZE); 
    memset (text, '.', DATASIZE); 
} 

HeaderType msg::getHeader(){ 
    return header; 
} 


void print(HeaderType header) { 
    std::cout << "Message ID: " << header.mID << std::endl; 
} 


byte * msg::getText(){ 
    return text; 
} 

을하고이 HeaderType 다음과 같습니다 : 클래스 msg이고 다음과 같이

typedef struct { 
    int mID; 
}HeaderType; 
,

Valgrind의 보고서 :

==3809== 20 bytes in 2 blocks are definitely lost in loss record 1 of 1 
==3809== at 0x4028876: malloc (vg_replace_malloc.c:236) 
==3809== by 0x80492BD: msg::msg(int) (in /home/linux/LCR-write/src/test) 
==3809== by 0x8049384: start_buffering() (in /home/linux/LCR-write/src/test) 

는 사실,이 코드 내부에 메모리 누수가 안 같아요. 버퍼는 항상 sending_thread에 의해 비워야합니다. 누군가 제발 잘못을 지적 해 주시겠습니까?

답변

1

문제는 start_buffering() 기능에 텍스트에 할당 된 메모리를 해제 MSG에 대한 소멸자가 필요합니다.

while (keep_buffering){ 
    msg m (counter); 
    while (buffer != NULL && keep_buffering){} 
    buffer = &m; 
    counter ++; 
} 

이 루프는 msg를 생성하고 그것의 생성자 text위한 메모리를 할당한다. 그런 다음 기다리고 다음을 수행합니다.

buffer = &m; 
    counter ++; 
    // end of loop 
    msg m (counter); 

루프가 끝나면 아무 것도 기다리지 않고 다음 반복을 시작합니다. 'old'msg m은 범위를 벗어나 새로운 msg m이 이전 스택과 정확히 같은 위치에 할당됩니다. 따라서 포인터 buffer은 여전히 ​​'유효'합니다 (실제로는 아닙니다!). 새 m을 가리 킵니다. 결과는 첫 번째 msg m에 대한 메모리 누수이며 더 중요한 것은 정의되지 않은 동작입니다. 더 이상 범위에 들지 않는 것을 사용할 수 없습니다.

또한 '공식적인'동기화 및 대기 메커니즘을 사용하는 것이 좋습니다.

+0

고마워요 @alain. 여전히 같은 문제. 비록 이것이 잘못된 것이지만 내 문제는 아닙니다. 편집을 확인하십시오. – Moi

+0

'~ msg()'에'free (text);'를 추가하고'msg * m = new msg (counter);'를 루프에 넣고'delete buffer;'를'sending() – alain

+0

== 4287 == 1 블록의 18 (8 직접, 10 간접) 바이트가 4의 손실 레코드 4에서 확실하게 손실됩니다. == 4287 == 연산자 : 0x402842F : 연산자 (버퍼 -> getText() new (unsigned int) (vg_replace_malloc.c : 255) == 4287 == 0x8048D79 : start_buffering() – Moi

1

당신은 생성자

class msg 
{ 
    private: 
     HeaderType header; 
     byte * text;  

    public: 
     msg(int ID); 
     HeaderType getHeader(); 
     byte * getText(); 
     ~msg() {free(text);} 
}; 
+0

이렇게하면'sending()'도 해제되므로 두 번 사용 가능합니다. – alain

+0

실은 그것이 그리워 할 것입니다. 텍스트는 msg의 개인 구현 세부 사항입니다. – pm100

+0

네, 맞습니다. – alain

관련 문제