我有一个程序,用作套接字客户端,这是代码
#include <stdio.h>
#include <signal.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sys/socket.h>
#include <netdb.h>
using namespace std;
void signalHandler(const int signal) {
cout << "SIGINT handled" << endl;
exit(EXIT_SUCCESS);
}
void error(const char *msg) {
perror(msg);
exit(0);
}
const string readStr(int descriptor) {
int n = 0;
string cmd = "";
char buffer[256];
memset(buffer, 0, sizeof(buffer));
while ((n = read(descriptor, buffer, 255)) != 0) {
if (n < 0) {
error("Error reading string");
}
// full string - just copy
if (n == 255) {
cmd += buffer;
memset(buffer, 0, sizeof(buffer));
}
else {
cmd += buffer;
break;
}
}
return cmd;
}
int main(int argc, char** argv) {
signal(SIGINT, signalHandler);
int fd, port = (argc >= 3 ? atoi(argv[2]) : 11212), n;
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
error("ERROR opening socket");
}
struct hostent *server = (argc >= 2 ? gethostbyname(argv[1]) : gethostbyname("localhost"));
if (server == NULL) {
error("ERROR no such host");
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
bcopy(server->h_addr, &addr.sin_addr.s_addr, server->h_length);
addr.sin_port = htons(port);
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
error("ERROR connecting");
}
string tmp;
while (1) {
cout << "Please enter the message: \n< " << flush;
tmp = readStr(0);
n = send(fd, tmp.c_str(), tmp.size(), 0);
if (n < 0) {
perror("ERROR writing to socket");
}
tmp = readStr(fd);
cout << "> " << tmp << endl;
}
close(fd);
return EXIT_SUCCESS;
}
当我发送SIGNINT以处理(CTRL + C)时,valgrind表示:
^ CSIGINT已处理
== 3798 ==
== 3798 ==堆摘要:
== 3798 ==在导出处使用:1块中39个字节
== 3798 ==总堆使用量:45个分配,44个释放,4,778个字节分配
== 3798 ==
== 3798 ==丢失记录1 of 1中可能会丢失1个块中的39个字节
== 3798 ==在0x402471C:运算符new(unsigned int)
(vg_replace_malloc.c:255)
== 3798 ==通过0x40DBB64:std::string::_ Rep::_ S_create(unsigned int,
unsigned int,std::allocator const&)(在
/usr/lib/libstdc++.so.6.0.15)
== 3798 ==通过0x1BFF403:???
== 3798 ==
== 3798 ==泄漏摘要:
== 3798 ==肯定会丢失:0字节(0块)
== 3798 ==间接丢失:0个字节,共0个块
== 3798 ==可能丢失:1个块中39个字节
== 3798 ==仍可到达:0字节,共0块
== 3798 ==已抑制:0字节,0块
== 3798 ==
== 3798 ==有关检测到的和抑制的错误的计数,请重新运行:-v
== 3798 ==错误摘要:来自1个上下文的1个错误(禁止显示:9个中的20个)
如果程序正确退出,例如,如果用
while(1)
重新标记int i = 0; while(i++ <= 2)
,则不会发生内存泄漏那么有人可以帮我解决这个问题吗?
最佳答案
当您从信号处理程序中调用std::exit
时,不会取消堆栈堆栈,并且不会破坏std::string
中的tmp
对象main
这样的局部变量。
由于tmp
不会在程序终止之前被销毁,因此它分配的内存永远不会释放,因此会泄漏。