c++ 我如何删除一个指针后,我用它作为一个正常的变量返回一个函数

tvokkenx  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(187)

我已经看过类似的问题,但他们都假设返回类型也是一个指针。如果这不是措辞好,我道歉,因为我有点新的c++。
所以我有如下函数:

//Converts string to LPCTSTR for dialog box
LPCTSTR CAnotherAttemptDlg::convertToLPCTSTR(std::string conversion)
{

    size_t convertedChars = 0;
    const size_t newsizew = conversion.size() + 1;
    wchar_t* wcstring = new wchar_t[newsizew];
    mbstowcs_s(&convertedChars, wcstring, newsizew, conversion.c_str(), _TRUNCATE);
    return wcstring;

}

字符串
我肯定你注意到我返回了一个指针作为结果,但是输出不应该是指针,所以我不能通过删除它被分配的指针来删除函数外部的指针,因为它不输出到指针。
注意:以防万一我被问到这应该做什么,它正在将字符串转换为LPCTSTR,这与wchar_t* 相同
Edit:为了澄清,这是调用此函数的块:

BOOL CAnotherAttemptDlg::OnInitDialog()
{

    string settingsLine;
    LPCTSTR defStrPath = L""; // = "C:\\Ste\\Runtime\\TestFiles";
    LPCTSTR defEndPath = L"";

    //grabs default start and end paths from FileTrams.ini, parses it into proper variables
    ifstream settingsStream("FileTrans.ini");

    while (getline(settingsStream, settingsLine)) {
        string delimiter = "=";
        string tokenOne = settingsLine.substr(0, settingsLine.find(delimiter)); 
        string tokenTwo = settingsLine.substr(settingsLine.find(delimiter) + 1, '10');

        if (tokenOne == "startPath") {
            defStrPath = convertToLPCTSTR(tokenTwo);
        }
        else if (tokenOne == "endPath") {
            defEndPath = convertToLPCTSTR(tokenTwo);
        }

    }

    

    settingsStream.close();
    

    CDialogEx::OnInitDialog();

    SetWindowLong(this->m_hWnd, GWL_STYLE, GetWindowLong(this->m_hWnd, GWL_STYLE) |  WS_SYSMENU);

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);         // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon

    // TODO: Add extra initialization here
    
    SetDlgItemText(IDC_MFCEDITBROWSE1, defStrPath);
    SetDlgItemText(IDC_MFCEDITBROWSE2, defEndPath);

    return TRUE;  // return TRUE  unless you set the focus to a control

    delete[] defStrPath;
    delete[] defEndPath;
}

vwhgwdsa

vwhgwdsa1#

我对你的问题的回答是双重的...

技术上:你可以delete[]

正如@someprogrammerdude和其他人所指出的,你的方法返回的是一个指向你新分配的wchar_t序列的指针:一个LPCWSTR,即一个指向Const Wchar“STRing”的(长)指针。你可以将delete[]应用于这个方法的调用结果。
但我真正想告诉你的是

规范性地:不要这样做。

有很多原因可以解释为什么你不应该写这样的函数或方法:
1.你应该避免使用raw newdelete当它们不是严格必要的时候;这是C++核心准则R.11。一个主要原因是,很容易忽略delete你已经分配给raw new的东西,并且没有自动化机制来确保你这样做。
1.你还应该
避免“拥有”内存的原始指针
;这是C核心指南R.3。具体来说,你的函数或方法签名不应该通过返回一个返回一个指针来产生所有权(你的函数会这样做)。相反,
1.使用... RAII自动管理内存;这是C
核心指南R.1。通常这意味着类在构造时分配资源,在析构时释放资源。具体来说,对于字符串,
1.如果你需要一个灵活的字符串缓冲区,而不是std::string-使用适当的缓冲区类std::vector,甚至std::stringstream,这取决于上下文。
1.但实际上-你的对话框类没有转换人的字符串的业务!毕竟,conversion参数是不知道的任何字符串类示例是在所有有关。如果你想能够转换一个字符串的char的到一个字符串的wchar_t的-这当然是可能的。阅读这个StackOverflow问题:
C++ Convert string (or char*) to wstring (or wchar_t*)
你会发现一个足够简单的答案(最初来自here):

std::wstring utf8_string_to_wstring(const std::string& str) {
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    return converter.from_bytes(str);
}

字符串
这将适用于UTF-8文本,特别是ASCII文本。但是-它在C++17中被弃用。我自己仍然使用它,但另一种替代方法是更Microsoft y的东西,比如建议的函数here

std::wstring utf8_string_to_wstring(const std::string& str) {
    int count = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), 
        str.length(), nullptr, 0);
    std::wstring wstr(count, 0);
    MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), 
        &wstr[0], count);
    return wstr;
}

mwngjboj

mwngjboj2#

所以在一些人的帮助下,我已经让程序在没有内存泄漏的情况下工作了。建议使用wstring而不是LPCTSTR,因为它会释放自己。
这是当前的代码:

BOOL CAnotherAttemptDlg::OnInitDialog()
{

    string settingsLine;
    wstring defStrPath = L""; // = "C:\\Ste\\Runtime\\TestFiles";
    wstring defEndPath = L"";

    //grabs default start and end paths from FileTrams.ini, parses it into proper variables
    ifstream settingsStream("FileTrans.ini");

    while (getline(settingsStream, settingsLine)) {
        string delimiter = "=";
        string tokenOne = settingsLine.substr(0, settingsLine.find(delimiter)); 
        string tokenTwo = settingsLine.substr(settingsLine.find(delimiter) + 1, '10');

        if (tokenOne == "startPath") {
            defStrPath = convertToLPCTSTR(tokenTwo);
        }
        else if (tokenOne == "endPath") {
            defEndPath = convertToLPCTSTR(tokenTwo);
        }

    }

    

    settingsStream.close();
    

    CDialogEx::OnInitDialog();

    SetWindowLong(this->m_hWnd, GWL_STYLE, GetWindowLong(this->m_hWnd, GWL_STYLE) |  WS_SYSMENU);

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);         // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon

    // TODO: Add extra initialization here
    
    SetDlgItemText(IDC_MFCEDITBROWSE1, defStrPath.c_str());
    SetDlgItemText(IDC_MFCEDITBROWSE2, defEndPath.c_str());

    return TRUE;  // return TRUE  unless you set the focus to a control

}

std::wstring CAnotherAttemptDlg::convertToLPCTSTR(std::string conversion)
{
    wstring temp = L"";

    size_t convertedChars = 0;
    const size_t newsizew = conversion.size() + 1;
    wchar_t* wcstring = new wchar_t[newsizew];
    mbstowcs_s(&convertedChars, wcstring, newsizew, conversion.c_str(), _TRUNCATE);
    temp = wcstring;
    delete[] wcstring;
    return temp;

}

字符串
需要指出的一个错误是,wstring在使用nullptr时似乎会出错,所以我只是用一个空字符串初始化,这可能不是最好的,但它现在工作。

相关问题