简体   繁体   中英

Is it necessary to avoid memory leak when returning pointer by using shared_ptr?

I have two functions for converting char array from gb2321 to utf-8 like,

#include <windows.h>
#include "memory.h"
#include <wchar.h>
#include <iostream>

using namespace std;

//GB2312 to UTF-8
char* G2U(const char* gb2312)
{
    int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0);
    wchar_t* wstr = new wchar_t[len + 1];
    memset(wstr, 0, len + 1);
    MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len);
    len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
    char* str = new char[len + 1];

    //what about using shared_ptr to release resource but how to modify following code?  
    //shared_ptr<char> str(new char[len + 1], default_delete<char[]>());

    memset(str, 0, len + 1);
    WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
    if (wstr) delete[] wstr;
    return str;
}

I read this code part in website and I was wondering if I should replace char* str = new char[len + 1]; with shared_ptr . If so, how to modify the following code, memset and WideCharToMultiByte ? PS, is there some method used by C not CPP ?

Instead of managing a raw pointer, or even a shared_ptr to manage a char pointer, you can simply use std::vector .
It has a constructor that accepts a size and a value (thus you don't need memset ). You can use std::vector::data to access the underlying data buffer.

Below you can see an example for str . A similar solution can be applied to wstr .

#include <vector>

std::vector<char> str(len + 1, 0);  // allocate size and set all elements to 0
//----------------------------------------vvvvvvvvvv
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str.data(), len, NULL, NULL);

Note:
In general it could be more straightforward using std::string . But until C++17 std::string::data returns a const char* which is incompatible with the Win32 API pointer which is used to write data into. You can still return std::string from your G2U function, by using:

return std::string(str.begin(), str.end());

If you can use C++17 you can use std::string instead of std::vector<char> and then you will be able to return str directly.

Update:
Regarding the "PS" at the end of your question - as far as I know the c language has no mechanism for automatic heap memory management.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM