例如,想象一个+
运算符重载来连接两个字符串;在这个例子中,两个奶酪的名称。这里我使用在堆上创建的tmp
变量。当方法退出时,这会导致内存泄漏吗?
Class Cheese {
private:
int nameLen; // Length of name
char * name; // C string
public:
Cheese(char * str); // Constructor
int getNameLen(); // Returns length of name
char * getName(); // Returns name
}
}
Cheese Cheese::operator + (const Cheese & rhs) {
char * tmp = new char[nameLen + rhs.getNameLen()];
strcpy(tmp, name);
strcat(tmp, rhs.getName());
return Cheese(tmp); // Is this a problem? Where does tmp get deleted?
}
用法:
Cheese c1("mozzarella");
Cheese c2("provolone");
printf("Cheese Blend: %s", (c1 + c2).getName());
因此,返回值会创建Cheese
的另一个实例。我担心的是,在堆上创建的tmp
是否会造成内存泄漏。它永远不会被删除,因为我将它作为return
语句的一部分包含在内,我不知道应该删除它。
这是一个合理的担忧吗?我需要这个tmp变量,还是我可以聪明而根本不使用它?将它放在堆栈上是最佳做法,如下所示?什么是最佳做法?
char * tmp[len + rhs.getLen()];
THX!
答案 0 :(得分:0)
IF
如果return Cheese(tmp); // Is this a problem? Where does tmp get deleted?
的构造函数生成输入参数的副本,则会出现问题。
当函数返回时,您可以使用智能指针删除Cheese
使用的内存。
tmp
如果您使用int len = nameLen + rhs.getNameLen() + 1; // Need the +1 for the null terminator
std::unique_ptr<char, std::default_delete<char[]>> tmp(new char[len]);
strcpy(tmp.get(), name);
strcat(tmp.get(), rhs.getName());
return Cheese(tmp.get());
作为成员变量std::string
的类型而不是name
,则可以在代码中消除这些不必要的复杂性。如果这样做,您可以删除char*
成员变量。然后,上述功能可以简化为:
nameLen