此代码块是否会导致内存泄漏?
char * foo = new char [20];
read(STDIN_FILENO, foo, 20);
string bar;
bar.reserve(20);
bar = foo;
delete[] foo;
我认为它不能,因为我们使用delete[]
释放大块内存。但是,对象bar
可能会有所不同。请分享你的观点。
答案 0 :(得分:5)
如果string bar;
,bar.reserve(20)
或bar = foo
中的任何一个投掷,则会有一个memleak。
您可以使用一些智能指针来避免这种情况:
auto foo = std::make_unique<char[]>(20);
答案 1 :(得分:0)
您不需要保留,如果从stdin读取的20个字节中的一个是\ 0,则只填充几个字节。
这是正确的代码:
char * foo = new char [20];
read(STDIN_FILENO, foo, 20);
string bar;
bar.assign(foo, 20);
delete[] foo;
...你可能在std :: string(构造函数或赋值)上遇到异常问题,但是只有在分配大量内存时才应该处理内存异常IMHO,因为如果分配20个字节最不确定你将无法正确处理异常。
如果我必须改进你的代码,无论是为了速度还是安全,我都会这样做:
char foo[20];
int len = read(STDIN_FILENO, foo, sizeof(foo));
string bar;
if (len > 0)
bar.assign(foo, len);
答案 2 :(得分:0)
@ Jarod42是正确的。你应该使用智能指针。但是,为了在没有智能指针的情况下解决这个问题(理解理论),试试这个:
char * foo = new char [20];
try{
read(STDIN_FILENO, foo, 20);
string bar;
bar.reserve(20);
bar = foo;
deleted=true;
delete[] foo;
}
catch (...){
delete[] foo;
throw;
}
如果第一行之一中存在异常,则会捕获异常,并且仍将删除foo。但是,除非您有令人信服的理由,否则应使用unique_ptr
或shared_ptr
答案 3 :(得分:0)
如果在编译时知道缓冲区大小,则不应使用new分配它。相反,你应该在堆栈上分配它,或者更好的是,在调整它之后直接读入字符串的缓冲区。这样,您可以确保代码和其他方面的最高效率,包括将分配与实际读数分开。