请考虑以下代码,包括两个线程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;
}
其中类msg
如下:
#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
:
typedef struct {
int mID;
}HeaderType;
瓦尔格林德报道:
==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
清空。请有人指出错误。
问题出在start_buffering()
函数上。
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);
当循环到达末尾时,它会开始下一次迭代,而无需等待任何内容。"旧"msg m
超出范围,并且在堆栈上与旧msg m
完全相同的位置分配新。因此,指针buffer
仍然是"有效的"(不是真的!),指向新的m
。结果是第一个msg m
的内存泄漏,更重要的是,未定义的行为。您不能再使用不在范围内的东西。
此外,我建议使用"官方"同步和等待机制。
你需要一个 msg 析构函数来释放为构造函数中的文本分配的内存
class msg
{
private:
HeaderType header;
byte * text;
public:
msg(int ID);
HeaderType getHeader();
byte * getText();
~msg() {free(text);}
};