【问题标题】:wcstombs & allocating memory for character array on heapwcstombs & 为堆上的字符数组分配内存
【发布时间】:2018-03-24 18:40:19
【问题描述】:

我正在读取一个包含单个宽字符行的文件。但是,我永远不知道它会持续多久。我已将其读入std::wstringinString,并设法凭空创建了多字节字符串(Q1 - 这些称为 r 值吗?)。 Q2 - 现在,我如何在堆中为此分配内存并获得指向它的智能指针?我不想使用newmalloc(并最终调用freedelete)或任何常量将其存储在堆栈中(因为我永远无法知道最大长度)。 Q3 - 我可以在这里使用make_sharedmake_unique 函数模板吗? Q4 - 具体来说,我可以得到一个像shared_ptr<char> 这样指向在堆上分配的char 数组的指针吗?

我尝试了类似以下的方法,

std::shared_ptr<char> MBString(const_cast<char*>(std::string(inString.begin(), inString.end()).c_str()));

它没有用。我在互联网上尝试了一些建议,但我还不知道该怎么做。

Q5 - 更不用说Wide char到多字节的转换了,一般来说,我如何在堆上分配任意长度的char字符串并获得指向它的智能指针?

std::wfstream inFile(L"lengthUnkown.txt", std::ios::in);
std::wstring inString;
inFile >> inString;
std::wcout << inString << std::endl; //prints correctly
std::cout << (const_cast<char*>(std::string(inString.begin(), inString.end()).c_str())) << std::endl; //this prints the line correctly as expected
//convert wide character string to multi-byte on the heap pointed, to by MBString 
//std::cout << MBString << std::endl; //I want to print the multi-byte string like this
return 0;

【问题讨论】:

  • 所以,你已经知道如何构造一个合适的std::string。剩下要做的就是应用这些知识:std::string MBString(inString.begin(), inString.end()); std::cout &lt;&lt; MBString;
  • 我没有意识到 std::string 是我正在寻找的东西,但是,有没有像共享指针或指向 char 数组的唯一指针之类的东西?
  • 原则上是有的——但为什么呢?如果您想管理chars 的序列,这就是std::string 的用途。
  • 太好了,谢谢。有人必须明确地告诉我。但是,现在,MBstring 指向的我的原始字符(来自文件)在哪里?他们在堆上(或者他们所说的免费商店)?还是在堆栈上?指针MBstring 在哪里?我是这种资源管理的新手,从未手动管理过内存。当我从文件中读取时,inString 中的字符在哪里,它们在堆上吗?顺便说一句,当我打印它时,这个(const_cast&lt;char*&gt;(std::string(inString.begin(), inString.end()).c_str())) 住在哪里?这就是他们所说的 r-value 吗?
  • 是的,std::string一般会在堆上分配内存来存储它管理的字符; std::wstring 也是如此。使用像std::string 这样的容器类的全部意义在于手动管理内存。

标签: c++11 memory-management smart-pointers wstring widechar


【解决方案1】:

资源不是最优但可靠:

wchar_t* mb2wstr(const char* inval) {
    size_t size = std::strlen(inval);
    #define OUTSZ (size+1)*sizeof(wchar_t)
    auto buf = (wchar_t*)std::malloc(OUTSZ);
    std::memset(buf, 0, OUTSZ);
    std::setlocale(LC_CTYPE,""); //  необходима, чтобы отработала "mbstowcs"
    size = std::mbstowcs(buf, inval, size);
    if ( size == (size_t)(-1) ) {
        std::free(buf);
        buf = nullptr;
    } else {
        buf = (wchar_t*)std::realloc(buf,OUTSZ);
    }
    return buf;
    #undef OUTSZ
}

char* wstr2mb(const wchar_t* inval) {
    size_t size = std::wcslen(inval);
    #define OUTSZ (size+1)*MB_CUR_MAX // Maximum length of a multibyte character in the current locale
    auto buf = (char*)std::malloc(OUTSZ);
    std::memset(buf, 0, OUTSZ);
    std::setlocale(LC_CTYPE,""); //  необходима, чтобы отработала "wcstombs"
    size = std::wcstombs(buf, inval, size*sizeof(wchar_t));
    if ( size == (size_t)(-1) ) {
        std::free(buf);
        buf = nullptr;
    } else {
        buf = (char*)std::realloc(buf,size+1);
    }
    return buf;
    #undef OUTSZ
}

const std::string pwchar2string(const wchar_t* inval) {
    char* tmp = wstr2mb(inval);
    string out{tmp};
    std::free(tmp);
    return out;
}
const std::wstring pchar2wstring(const char* inval) {
    wchar_t* tmp = mb2wstr(inval);
    wstring out{tmp};
    std::free(tmp);
    return out;
}

const wstring string2wstring(const string& value) {
    return pchar2wstring(value.c_str());
}
const string wstring2string(const wstring& value) {
    return pwchar2string(value.c_str());
}
const wchar_t* char2wchar(const char* value) {
    return pchar2wstring(value).c_str();
}
const char* wchar2char(const wchar_t* value) {
    return pwchar2string(value).c_str();
}

【讨论】:

    猜你喜欢
    • 2012-10-01
    • 2018-09-17
    • 2016-03-25
    • 2019-05-20
    • 2022-01-17
    • 1970-01-01
    • 2017-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多