删除其范围之外的已分配(新)对象 目前我在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; }
函数调用看起来是这样的删除其范围之外的已分配(新)对象 目前我在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; },c++,C++,函数调用看起来是这样的 for(auto &person : persons) ... SomeClass::cpy(&(person.name_), new_name); ... 我的问题是删除其范围之外的tmp变量。我不能在这个范围的末尾删除它,因为我需要它的值。将类析构函数与delete[]name\uux似乎违反了内存。您正在将tmp返回到*dest。因此,当您处理完它后,您可以删除person.name假设person.name是字符*您将tmp返回到*des
for(auto &person : persons)
...
SomeClass::cpy(&(person.name_), new_name);
...
我的问题是删除其范围之外的tmp变量。我不能在这个范围的末尾删除它,因为我需要它的值。将类析构函数与
delete[]name\uux代码>似乎违反了内存。您正在将tmp返回到*dest。因此,当您处理完它后,您可以删除person.name
假设person.name
是字符*
您将tmp返回到*dest。因此,当你完成它时,你可以使用<代码>删除人.NAME> <代码>,假设个人。NAMEX是< C++ > CAR* .< /P> 在现代C++中,使用裸体指针来拥有对象是一个坏的实践。改为使用std::unique_ptr,这将确保删除内存时释放内存。最好是从函数返回值,而不是使用输出参数。将方法的签名更改为
std::unique_ptr<char> SomeClass::cpy(const char* origin)
std::unique\u ptr SomeClass::cpy(常量字符*原点)
这样,std::unique_ptr
将负责删除不再需要的内存
注意,对于您的特定用例 STD::String 可以是更好的替代方案,因为它是专门为处理字符串而设计的。
在现代C++中,使用裸体指针来拥有对象是一个坏的做法。改为使用std::unique_ptr,这将确保删除内存时释放内存。最好是从函数返回值,而不是使用输出参数。将方法的签名更改为
std::unique_ptr<char> SomeClass::cpy(const char* origin)
std::unique\u ptr SomeClass::cpy(常量字符*原点)
这样,std::unique_ptr
将负责删除不再需要的内存
请注意,对于您的特定用例,std::string
是一个更好的选择,因为它是专门为处理字符串而设计的。快速浏览:
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\uu代码>完全可以接受
然而。。。
这看起来是一个很好的地方,可以不做上述任何一项,并减少std::string
带来的内存管理问题<代码>标准::字符串
为您照看它的内存
std::string SomeClass::cpy(const char* origin)
{
return std::string(origin);
}
及
一旦person.name
从char*
转换为std::string
。但是一旦这样做了,SomeClass::cpy
就是多余的,因为
person.name_ = new_name;
将为您完成所有工作。快速浏览:
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\uu代码>完全可以接受
然而。。。
这看起来是一个很好的地方,可以不做上述任何一项,并减少std::string
带来的内存管理问题<代码>标准::字符串
为您照看它的内存
std::string SomeClass::cpy(const char* origin)
{
return std::string(origin);
}
及
一旦person.name
从char*
转换为std::string
。但是一旦这样做了,SomeClass::cpy
就是多余的,因为
person.name_ = new_name;
将为您完成所有工作。超出其范围是什么意思?我强烈建议您使用std::string
和引用参数,而不是手动内存操作和指针。由于我在函数内部分配tmp,因此无法从其他任何地方删除它。美(和恐怖)动态分配的范围就是你所说的范围。@Mer0winger当然是。您可以从任何可以访问指针的位置删除它。只需确保它被删除一次。在它的范围之外是什么意思?我强烈建议您使用std::string
和引用参数,而不是手动内存操作和指针。由于我在函数内部分配tmp,我无法从其他任何地方删除它。美(和恐怖)动态分配的范围就是你所说的范围。@Mer0winger当然是。您可以从任何可以访问指针的位置删除它。只需确保它被删除一次。在现代C++中,使用裸机指针被认为是一个坏的做法有点误导。使用原始指针是不好的做法。非拥有指针是好的。在现代C++中,使用裸机指针被认为是一个坏的做法有点误导。使用原始指针是不好的做法。非拥有指针就可以了。您甚至可以将其设置为一个,并使用std::string SomeClass::cpy(std::string origin){return origin;}
@NathanOliver Good point。还提供了一个页面和一个半长的熨平板来解释传递值和传递引用的可能性。您甚至可以在上面使用std::string SomeClass::cpy(std::string origin){return origin;}
@NathanOliver Good point。此外,还可以使用一页半长的熨平板来解释“通过值”与“通过引用”。