C ++:在被本地字符串捕获后释放还是销毁malloc的char *?

时间:2018-10-18 13:05:34

标签: c++ memory-management c-strings

假设我执行以下操作:

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());是否有效?

4 个答案:

答案 0 :(得分:5)

一旦您完成

std::string data(get_data(...));

无法取回get_data()返回的指针,因此您将泄漏该内存。要解决此问题,只需get_data()首先返回一个std::string,这样就完全不必担心内存管理。那会给你

std::string get_data(...) {
    std::string data(length, '\0');
    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);

答案 1 :(得分:2)

您无法致电free(data.c_str());或类似电话。 std::string管理自己的内存,甚至一旦c_str()超出范围,从std::string获得的指针也会自动失效。

但是,您确实需要释放从函数调用返回的c_stylestd::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;
}

答案 2 :(得分:2)

  

有什么办法释放select distinct name from billing_account where user_status = 'Active' and user_id ='1'; 分配的内存?

不,您丢失了指向它的指针。

  

评论过的get_data()是否有用?

不。 free(data.c_str());将您的数据复制到它拥有和管理的新字符串中。您无法合法地取消分配std::string自己分配的内存,也无法解决必须取消分配原始分配的内存的问题。

始终使用std::string(首选!),或者先在std::string内捕获指针:

main

问题是,这不是异常安全的,这就是为什么我们首先拥有int main() { auto cstr = get_data(...); std::string data(cstr); free(cstr); } 之类的好东西的原因。可以使用一些自由的std::stringtry来解决,但是会很丑。

此外,由于您已经拥有catch,大概是有原因的,您可能会考虑在已分配的实际内存上使用get_data,除非您确实需要string_view作为拥有副本。

data

(其他地方的评论表明这可能是您真正想要的。)

现在尝试用int main() { auto cstr = get_data(...); std::string_view data(cstr); // no copy! just features free(cstr); } 返回具有明确所有权和生命周期语义(get_datastd::unique_ptrstd::vector?..大声笑)的东西,您就很高兴了。 / p>

答案 3 :(得分:1)

您不能删除指针,没有保留对其的引用。您需要这样做:

int main() {
   char* cstr = get_data(...);
   std::string data(cstr);
   free(cstr);
   return 0;
}

或者更好地将数据直接写入字符串:

std::string get_data(...) {
    std::string data(length, '\0');
    load_c_string_with_my_c_function(&data[0], data.size(), input);
    return data;
}

您可能需要在std::string的长度上加1和/或将data.size()-1传递到load_c_string_with_my_c_function,具体取决于{{1 }}。