目前我在C ++中遇到了一些内存管理问题。
void SomeClass::cpy(char** dest, const char* origin)
{
int len = strlen(origin);
char* tmp = new char[len+1];
strncpy(tmp, origin, len);
tmp[len] = '\0';
*dest = tmp;
}
函数调用看起来像
for(auto &person : persons)
...
SomeClass::cpy(&(person.name_), new_name);
...
我的问题是删除其范围之外的tmp变量。我无法在此范围的末尾删除它,因为我需要它的值。使用带有delete[] name_;
的类析构函数似乎违反了内存。
答案 0 :(得分:1)
在现代C ++中,使用裸指针拥有对象被认为是一种不好的做法。请改用std :: unique_ptr,以确保在删除内存时释放内存。并且最好从函数返回值而不是使用输出参数。将方法的签名更改为
std::unique_ptr<char> SomeClass::cpy(const char* origin)
这种方式std::unique_ptr
将负责在不再需要时删除内存。
请注意,对于您的特定用例std::string
,它可以是更好的选择,因为它专门用于处理字符串。
答案 1 :(得分:1)
快速浏览:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="TestPU" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
</properties>
</persistence-unit>
</persistence>
只是动态分配了一块内存。此块将一直存在,直到使用void SomeClass::cpy(char** dest, const char* origin)
{
int len = strlen(origin);
char* tmp = new char[len+1];
手动释放。
delete[]
先前分配的内存块已分配给 strncpy(tmp, origin, len);
tmp[len] = '\0';
*dest = tmp;
。提供dest
的任何人都可以随时使用dest
释放此内存,只要每次分配只执行一次。
delete[]
现在是来电者
}
指定SomeClass::cpy(&(person.name_), new_name);
和person.name_
是同一个。这意味着dest
完全可以接受。
这看起来是一个很好的地方,不会做上述任何事情,并减少delete[] person.name_;
的内存管理困境。 std::string
为你照顾它。
std::string
和
std::string SomeClass::cpy(const char* origin)
{
return std::string(origin);
}
person.name_ = SomeClass::cpy(new_name);
从person.name_
转换为char *
后。但是,一旦完成,std::string
就是多余的,因为
SomeClass::cpy
将为您完成所有工作。
答案 2 :(得分:0)
你要将tmp返回* dest。因此,当您完成该操作后,您可以delete person.name_
假设person.name_
是char*
。