C++:在被本地字符串捕获后释放或销毁 malloc 的 char *?
C++: free or destroy malloc'd char * after it is captured by a local string?
假设我执行以下操作:
char *get_data(...) {
char *c_style = (char *) malloc(length * sizeof(char));
load_c_string_with_my_c_function(c_style, length, input);
return c_style;
}
int main() {
std::string data(get_data(...));
// free(data.c_str()); ?? -- are the malloc'd bytes now managed?
return 0;
}
有什么方法可以释放get_data()
分配的内存吗?评论 free(data.c_str());
有用吗?
您不能拨打电话 free(data.c_str());
或类似的电话。 std::string
管理自己的内存,即使 c_str()
获得的指针也会在 std::string
超出范围后自动失效。
但是,您确实需要释放从函数调用返回的 c_style
。 std::string
可以处理它自己的内存,但它只是 malloc
的内存的一个副本,不受管理。
这样做:
int main() {
char *result = (get_data(...)
std::string data(result);
// free(data.c_str()); ?? -- are the malloc'd bytes now managed?
free(result);
return 0;
}
一旦你这样做了
std::string data(get_data(...));
无法取回 get_data()
return 编辑的指针,因此您会泄漏该内存。要解决此问题,首先需要 get_data()
return 一个 std::string
,这样您根本不必担心内存管理。那会给你
std::string get_data(...) {
std::string data(length, '[=11=]');
load_c_string_with_my_c_function(data.data(), length, input); // requires C++17
// load_c_string_with_my_c_function(&data[0], length, input); // use this for pre-C++17 compilers
return data;
}
现在没有内存泄漏。如果你不能这样做那么你需要捕获指针,用它来初始化字符串,然后像
一样释放指针
char* ret = get_data(...);
std::string data(ret);
free(ret);
您不能删除指针,因为您没有保留对它的引用。你需要做的:
int main() {
char* cstr = get_data(...);
std::string data(cstr);
free(cstr);
return 0;
}
或者直接将数据写入字符串更好:
std::string get_data(...) {
std::string data(length, '[=11=]');
load_c_string_with_my_c_function(&data[0], data.size(), input);
return data;
}
您可能需要将 std::string
and/or 传递 data.size()-1
到 load_c_string_with_my_c_function
的长度加 1,具体取决于 length
参数的规范load_c_string_with_my_c_function
个。
Is there any way to release the memory that get_data()
allocated?
不,您丢失了指向它的指针。
Would the commented free(data.c_str());
Work?
没有。 std::string
将您的数据复制到它拥有和管理的新字符串中。您不能合法地取消分配 std::string
自己分配的内存,这也不能解决必须取消分配原始分配内存的问题。
要么始终使用 std::string
(首选!),要么首先捕获 main
内的指针:
int main()
{
auto cstr = get_data(...);
std::string data(cstr);
free(cstr);
}
问题是,这不是异常安全的,这就是为什么我们首先拥有像 std::string
这样的好东西。它可以用一些自由 try
和 catch
来解决,但它会很难看。
此外,由于您已经拥有 get_data
,大概是出于某种原因,您可能会考虑 string_view
超过您已经分配的实际内存,除非您确实需要 data
成为拥有的副本。
int main()
{
auto cstr = get_data(...);
std::string_view data(cstr); // no copy! just features
free(cstr);
}
(其他地方的评论表明这可能是您真正想要的。)
现在尝试拥有 get_data
return 具有明确所有权和生命周期语义的东西(std::unique_ptr
?std::vector
?std::string
?.. 哈哈)和你是金色的。
假设我执行以下操作:
char *get_data(...) {
char *c_style = (char *) malloc(length * sizeof(char));
load_c_string_with_my_c_function(c_style, length, input);
return c_style;
}
int main() {
std::string data(get_data(...));
// free(data.c_str()); ?? -- are the malloc'd bytes now managed?
return 0;
}
有什么方法可以释放get_data()
分配的内存吗?评论 free(data.c_str());
有用吗?
您不能拨打电话 free(data.c_str());
或类似的电话。 std::string
管理自己的内存,即使 c_str()
获得的指针也会在 std::string
超出范围后自动失效。
但是,您确实需要释放从函数调用返回的 c_style
。 std::string
可以处理它自己的内存,但它只是 malloc
的内存的一个副本,不受管理。
这样做:
int main() {
char *result = (get_data(...)
std::string data(result);
// free(data.c_str()); ?? -- are the malloc'd bytes now managed?
free(result);
return 0;
}
一旦你这样做了
std::string data(get_data(...));
无法取回 get_data()
return 编辑的指针,因此您会泄漏该内存。要解决此问题,首先需要 get_data()
return 一个 std::string
,这样您根本不必担心内存管理。那会给你
std::string get_data(...) {
std::string data(length, '[=11=]');
load_c_string_with_my_c_function(data.data(), length, input); // requires C++17
// load_c_string_with_my_c_function(&data[0], length, input); // use this for pre-C++17 compilers
return data;
}
现在没有内存泄漏。如果你不能这样做那么你需要捕获指针,用它来初始化字符串,然后像
一样释放指针char* ret = get_data(...);
std::string data(ret);
free(ret);
您不能删除指针,因为您没有保留对它的引用。你需要做的:
int main() {
char* cstr = get_data(...);
std::string data(cstr);
free(cstr);
return 0;
}
或者直接将数据写入字符串更好:
std::string get_data(...) {
std::string data(length, '[=11=]');
load_c_string_with_my_c_function(&data[0], data.size(), input);
return data;
}
您可能需要将 std::string
and/or 传递 data.size()-1
到 load_c_string_with_my_c_function
的长度加 1,具体取决于 length
参数的规范load_c_string_with_my_c_function
个。
Is there any way to release the memory that
get_data()
allocated?
不,您丢失了指向它的指针。
Would the commented
free(data.c_str());
Work?
没有。 std::string
将您的数据复制到它拥有和管理的新字符串中。您不能合法地取消分配 std::string
自己分配的内存,这也不能解决必须取消分配原始分配内存的问题。
要么始终使用 std::string
(首选!),要么首先捕获 main
内的指针:
int main()
{
auto cstr = get_data(...);
std::string data(cstr);
free(cstr);
}
问题是,这不是异常安全的,这就是为什么我们首先拥有像 std::string
这样的好东西。它可以用一些自由 try
和 catch
来解决,但它会很难看。
此外,由于您已经拥有 get_data
,大概是出于某种原因,您可能会考虑 string_view
超过您已经分配的实际内存,除非您确实需要 data
成为拥有的副本。
int main()
{
auto cstr = get_data(...);
std::string_view data(cstr); // no copy! just features
free(cstr);
}
(其他地方的评论表明这可能是您真正想要的。)
现在尝试拥有 get_data
return 具有明确所有权和生命周期语义的东西(std::unique_ptr
?std::vector
?std::string
?.. 哈哈)和你是金色的。