c++ - 如何使这段代码不易发生内存泄漏?

标签 c++ memory-management

作为介绍,请注意,我是一名 Java 程序员,仍在习惯 C++ 中的内存管理问题。

我们有一个基类,用于将对象编码为 ASCII 字符字符串。本质上,该类使用 stringstream 类成员将不同的数据类型转换为一个长字符串,然后向调用者返回一个包含编码对象数据的 char* 。

在内存泄漏测试中,我发现我们使用的实现似乎很容易造成内存泄漏,因为用户必须始终记住删除方法的返回值。以下是代码相关部分的摘录:

    char* Msg::encode() 
    {
        // clear any data from the stringstream
        clear();
        if (!onEncode()) {
            return 0;
        }

        // need to convert stringstream to char*
        string encoded = data.str();
                    // need to copy the stringstream to a new char* because 
                    // stringstream.str() goes out of scope when method ends
        char* encoded_copy = copy(encoded);
        return encoded_copy;
    }

    bool Msg::onEncode(void)
    {
        encodeNameValue(TAG(MsgTags::TAG_USERID), companyName);
        encodeNameValue(TAG(MsgTags::TAG_DATE), date);
        return true;
    }

    bool EZXMsg::encodeNameValue(string& name, int value)
    {
        if(empty(value))
        {
            return true;
        }
                    // data is stringstream object
        data << name << TAG_VALUE_SEPARATOR << value << TAG_VALUE_PAIRS_DELIMITER;
        return true;
    }


    char* copy(string& source) {
        char *a=new char[source.length() +1];
        a[source.length()]=0;
        memcpy(a,source.c_str(),source.length());
        return a;
    }

更新

嗯 - 我应该更准确地了解 encode() 的结果是如何使用的。它被传递给 boost:async_write,并且程序崩溃,因为我相信字符串在 async_write 完成之前超出了范围。看来我需要将返回的字符串复制到一个类成员,该成员在发送消息的类的生命周期内一直处于事件状态(?)。

这是 encode() 方法的实际使用方式(在我将 的返回值更改为 string 之后):

void iserver_client::send(ezx::iserver::EZXMsg& msg) {
       string encoded = msg.encode();   
       size_t bytes = encoded.length();
       boost::asio::async_write(socket_, boost::asio::buffer(encoded, bytes), boost::bind(&iserver_client::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));    
}

看起来正确的方法是维护一个异步写入的字符串队列/列表/vector 。如前所述here (也在 boost chat_client 示例中)。 (但这是一个单独的问题。)

最佳答案

对于这个问题: 在你的复制函数中,你返回一个指向堆内存的指针!所以用户可能会造成内存泄漏,我认为你不能使用这个复制函数,你可以在你的编码函数中这样做:

return data.str();

如果想得到一个char*,可以使用string的成员函数:c_str(), 就像这样:

string ss("hello world");
const char *p = ss.c_str();

如果您使用堆栈字符串对象,则不会造成内存泄漏,

关于c++ - 如何使这段代码不易发生内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17636088/

相关文章:

memory-management - 内核线程对内核地址空间的任意读取是否会引发 panic ?

C++ - 重载 operator new 并提供额外的参数

c++ - "expected ' ; zeromq 的 ' at the end of declaration list"错误

c++ - 如何在 C++ 中编写一个函数,该函数采用可变数量的 double vector ?

c++ - 为什么这个函数不输出小数

c++ - 获取多行输入以在 C++ 中进行解析

c++ - 在 C++ 中使用 ifstream 打开和关闭后,.txt 文件不再由 snmptrapd 守护进程写入

iphone - 引用计数对象在被释放后被使用

python - Python中的变量是如何分配内存的?

java - 在 Java 中检测低可用内存