我正在调查一个内存泄漏问题,从我的观察来看,问题是这样的:
int main(){
char *cp = 0;
func(cp);
//code
delete[] cp;
}
void func(char *cp){
cp = new char[100];
}
//code注释处,我原本期望cp指向已分配的内存,但它仍然是一个空指针,意味着我从未删除这段内存。我做错了什么?
您正在将 cp
赋值为分配的内存的值。然而,这是一个在堆栈上的变量:是主函数中 cp
的副本!cp
局限于您当前所在的函数。
您想要的是一个引用:
void func(char *& cp)
这将会将cp
作为传递进来的参数进行别名处理。
void func(char *cp){
cp = new char[100];
}
在这个函数中,char *cp是通过“拷贝”传递的指针,这意味着它们指向同一个内存地址,但它们不是同一个指针。当你在函数内部改变指针,使其指向其他地方时,原来传递的指针将继续指向0。参数cp是函数的局部变量——更改它不会影响函数外的任何内容。更好的编写函数的方式是:
char * func(){
return new char[100];
}
虽然与您的问题直接无关,但您应该使用std::string和std::vector而不是动态分配数组。
虽然引用在提供直观抽象方面非常出色,而C++11的右值引用进一步增强了函数链接(和其他深奥的编码),但可以争论它们是否提供任何安全性(参见为什么引用被认为比指针更安全)。 在需要在ansi c和c ++中维护类似代码库的情况下,最好使用指向指针函数参数来解决上述问题。
#include <iostream>
using namespace std;
void func(char ** cp) {
*cp = new char[100];
//do something useful
(*cp)[0] = 'A';
}
void func(char *& cp) {
cp = new char[100];
//do something useful
cp[0] = 'B';
}
int main(int argc, char** argv) {
char * cp;
//pointer to pointer
func(&cp);
cout << "Index 0 : " << cp[0] << '\n' << flush;
delete[] cp; //remember to delete!!
//pointer to ref
func(cp);
cout << "Index 0: " << cp[0] << '\n' << flush;
delete[] cp;
return 0;
}
cp
。cp
的一个副本。应该使用引用代替。
class CBuf
{
public
CBuf()
{
iBuf = new char[100];
}
~CBuf
{
delete[] iBuf;
}
char* func()
{
//do stuff;
return iBuf;
}
private:
char* iBuf;
};
int main()
{
CBuf cb;
char* mychar = cb.func();
//do stuff with character array
//destructor gets called here because cb goes out of scope
}
然而,在C编程中,有时候必须要有某种函数来创建数组。因此,在C编程中,你可以用CreateCBuf
和DestroyCBuf
函数替换析构函数。这样,你的库的用户就会知道返回的缓冲区需要被销毁。
cbuf
应该是cp
才对? - GManNickG