Почему MFC C++ CString(const char*) полностью меняет значение const char *?
Надеюсь, название было достаточно хорошим, чтобы объяснить, с чем у меня проблемы. Я думаю, что как только я решу эту проблему, мой проект будет в значительной степени завершен. Просто обратите внимание, оба проекта скомпилированы под Unicode.
Я работаю с CLI/C++
DLL, которая принимает LPCTSTR
и возвращает const char*
, Если я храню значение возврата в const char*
в моем проекте, проходя через него, я вижу, что возвращаемое значение - это то, что я ожидаю получить.
Теперь, если я сделаю следующее:
LPCTSTR strValue = L"test";
const char* Return = MethodCall(strValue);
LPCTSTR Final = CString(Return);
Return будет равен "Xmkk=Asmks" (что и должно быть). Этот метод шифрует строку. Проблема в том, когда я делаю CString
, Final будет равен "" 㹙癞鞮᠀諸²⤐²". Как мне включить onst char*
в LPCTSTR
без изменения своих данных
Спасибо.
3 ответа
После уничтожения CString(Return) (это происходит "прямо на следующей строке после его построения") "Final" указатель указывает на освобожденный кусок памяти (который был внутренним буфером CString(Return)). На этом этапе содержимое памяти, на которое он указывает, не определено, а разыменование - неопределенное поведение.
Чтобы использовать указатель на внутренний буфер safelly, вы должны убедиться, что CString, которой принадлежит буфер, жив, пока есть указатель.
LPCTSTR strValue = L"test";
const char* Return = MethodCall(strValue);
LPCTSTR PointerToBuffer= 0;
{
CString ReturnStringObj(Return);
PointerToBuffer = ReturnStringObj;
// Can safelly use your pointer here
}
// Here ReturnStringObj is killed and pointer dereferencing is invalid here
Как упоминает vnm, вы создаете временный CString
объект, вызывая его конструктор в строке 3, и затем этот объект немедленно уничтожается. Это освобождает часть памяти, которую он использовал для вашего буфера, что означает, что любые попытки доступа к данным, хранящимся в этой памяти, будут неопределенным поведением. Вот почему ваша строка выглядит искаженной: она уже удалена.
Если вы новичок в C++, вам нужно убедиться, что вы понимаете время жизни объекта. Это сделало бы написание этого кода значительно проще.
Решение состоит в том, чтобы ваш CString
объект не будет уничтожен, пока вы не покончили с ним. Если вам нужно, чтобы объект существовал только внутри вашей функции, вы можете оставить его как временный объект, созданный внутри этой функции. Если вам нужно, чтобы он существовал вне этой функции, вам нужно создать его на более высоком уровне или сохранить указатель на него.
Обратите внимание, что CString
объекты неявно преобразуются в LPCTSTR
,
При условии, что вам нужно только CString
Чтобы объект оставался живым в рамках вашей функции, вы могли бы написать следующий код:
{
// Declare a string literal
LPCTSTR strValue = L"test";
// Encrypt the string
const char* strReturn = MethodCall(strValue);
// Create a CString object representing the encrypted string
CStringA myString(strReturn);
// Do something with myString, like display it in a message box
// (Remember that it's an ANSI (non-Unicode) string!)
// ...
MessageBoxA(NULL, myString, NULL, MB_OK);
// ...
// myString (your CString object) gets destroyed here
}
Что вы можете сделать, это создать новый CStringA
возразить и бросить это const char*
для финала. Тогда Final останется действительным до тех пор, пока определен CStringA.
Я бы рекомендовал не использовать CString
(или же CStringW
) для хранения, к которому вам нужно получить доступ, используя const char*
,