wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was corrupted
От: derasa  
Дата: 10.07.13 11:52
Оценка: -1 :))) :)
wchar_t curt[] = L"";
// тип CurText — wstring
int i;
for (i = 0; i < CurText.size(); i++) // преобразую wstring к wchar_t. Возможно нужно по другому
{
curt[i] = CurText[i];
}

curt[i] = '\0';
OpenClipboard(0);
EmptyClipboard();
HGLOBAL hStrMem = GlobalAlloc(GMEM_MOVEABLE, sizeof(curt));
void* pStrMem = GlobalLock(hStrMem);
memcpy(pStrMem, curt, sizeof(curt));
GlobalUnlock(pStrMem);
SetClipboardData(CF_UNICODETEXT, hStrMem);
CloseClipboard();
return 0;

10.07.13 18:06: Перенесено модератором из 'C/C++' — Кодт
11.07.13 01:55: Перенесено модератором из 'C/C++. Прикладные вопросы' — Кодт
Re: wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was corru
От: Кодт Россия  
Дата: 10.07.13 13:55
Оценка: 2 (1)
Здравствуйте, derasa, Вы писали:
D>wchar_t curt[] = L"";

Разместил на стеке массив из 1 элемента (ровно столько элементов содержится в строке L"": там концевой ноль, и всё)

D>for (i = 0; i < CurText.size(); i++) // преобразую wstring к wchar_t. Возможно нужно по другому
D>{
D>     curt[i] = CurText[i];
D>}

В первый элемент (там, где был ноль) положил первую букву, во второй элемент... стоп, а где же находится второй элемент, если массив одноэлементный?
Правильно, остальные элементы находятся поверх предыдущих переменных, поверх заголовка кадра, поверх адреса возврата, поверх аргументов функции, поверх переменных вызывающей стороны....

D>curt[i] = '\0';
D>OpenClipboard(0);
D>EmptyClipboard();
D>HGLOBAL hStrMem = GlobalAlloc(GMEM_MOVEABLE, sizeof(curt));

Выделили память под одноэлементную строку.
D>void* pStrMem = GlobalLock(hStrMem);
D>memcpy(pStrMem, curt, sizeof(curt));

спасибо, что скопировали одноэлементную строку, а не CurrText.size() элементов — а то ещё бы и кучу убили, в придачу к уже убитому стеку
D>GlobalUnlock(pStrMem);
D>SetClipboardData(CF_UNICODETEXT, hStrMem);
D>CloseClipboard();
D>return 0;

Тадам!!! Стек у нас убит, return не знает, ни куда возвращаться, ни как...

А ведь всё делается гораздо проще
wchar_t const* curt = CurText.c_str();
// внезапно, sizeof(curt) = sizeof(void*) = 4 или 8, в зависимости от платформы. Не наступи на эти грабли ниже.
size_t num_bytes = (CurText.size()+1)*sizeof(wchar_t);
.....
GlobalAlloc(...num_bytes);
.....
memcpy(...num_bytes);
.....
Перекуём баги на фичи!
Re: wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was corru
От: derasa  
Дата: 10.07.13 11:54
Оценка:
А текст вида curt = L"тест копирования" прекрасно копируется в буфер обмена.

Ошибка Stack around the variable 'curt' was corrupted
происходит после выхода из функции
Re[2]: wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was co
От: derasa  
Дата: 10.07.13 14:27
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, derasa, Вы писали:

К>
D>>wchar_t curt[] = L"";
К>

К>Разместил на стеке массив из 1 элемента (ровно столько элементов содержится в строке L"": там концевой ноль, и всё)

К>
D>>for (i = 0; i < CurText.size(); i++) // преобразую wstring к wchar_t. Возможно нужно по другому
D>>{
D>>     curt[i] = CurText[i];
D>>}
К>

К>В первый элемент (там, где был ноль) положил первую букву, во второй элемент... стоп, а где же находится второй элемент, если массив одноэлементный?
К>Правильно, остальные элементы находятся поверх предыдущих переменных, поверх заголовка кадра, поверх адреса возврата, поверх аргументов функции, поверх переменных вызывающей стороны....

К>
D>>curt[i] = '\0';
D>>OpenClipboard(0);
D>>EmptyClipboard();
D>>HGLOBAL hStrMem = GlobalAlloc(GMEM_MOVEABLE, sizeof(curt));
К>

К>Выделили память под одноэлементную строку.
К>
D>>void* pStrMem = GlobalLock(hStrMem);
D>>memcpy(pStrMem, curt, sizeof(curt));
К>

К>спасибо, что скопировали одноэлементную строку, а не CurrText.size() элементов — а то ещё бы и кучу убили, в придачу к уже убитому стеку
К>
D>>GlobalUnlock(pStrMem);
D>>SetClipboardData(CF_UNICODETEXT, hStrMem);
D>>CloseClipboard();
D>>return 0;
К>

К>Тадам!!! Стек у нас убит, return не знает, ни куда возвращаться, ни как...

К>А ведь всё делается гораздо проще

К>
К>wchar_t const* curt = CurText.c_str();
К>// внезапно, sizeof(curt) = sizeof(void*) = 4 или 8, в зависимости от платформы. Не наступи на эти грабли ниже.
К>size_t num_bytes = (CurText.size()+1)*sizeof(wchar_t);
К>.....
К>GlobalAlloc(...num_bytes);
К>.....
К>memcpy(...num_bytes);
К>.....
К>


Спасибо, заработало!

Щас будем извлекать из буфера
Re[3]: wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was co
От: Ops Россия  
Дата: 10.07.13 15:47
Оценка:
Здравствуйте, derasa, Вы писали:

D>Спасибо, заработало!


D>Щас будем извлекать из буфера


Только еще GlobalFree добавь. А вообще:

Note The global functions have greater overhead and provide fewer features than other memory management functions. New applications should use the heap functions unless documentation states that a global function should be used. For more information, see Global and Local Functions.

Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[2]: wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was co
От: derasa  
Дата: 10.07.13 20:10
Оценка:
Здравствуйте, Кодт, Вы писали:

С копированием из буфера тоже проблемы. Строка с иероглифами получается. Пример взял из инета, поменял на lptstr. Что неправильно?

HGLOBAL buf = NULL;
LPTSTR lptstr;
if(IsClipboardFormatAvailable(CF_TEXT)) { // если в буфере формат данных(текса)
if(OpenClipboard(GetForegroundWindow())) { // открываем буфер-обмена
// получаем указатель на буфер-обмена
if((buf = (HGLOBAL) GetClipboardData(CF_TEXT)) != NULL)
{
lptstr = (LPTSTR)GlobalLock(buf);
}
}
}
Re[4]: wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was co
От: derasa  
Дата: 10.07.13 20:12
Оценка:
Здравствуйте, Ops, Вы писали:

Ops>Здравствуйте, derasa, Вы писали:


D>>Спасибо, заработало!


D>>Щас будем извлекать из буфера


Ops>Только еще GlobalFree добавь. А вообще:

Ops>

Ops>Note The global functions have greater overhead and provide fewer features than other memory management functions. New applications should use the heap functions unless documentation states that a global function should be used. For more information, see Global and Local Functions.


Если я вас правильно понял — то я использую устаревшие функции? Можете поделиться примером использования новых функций в контексте моей задачи?
Re[5]: wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was co
От: Ops Россия  
Дата: 10.07.13 20:52
Оценка:
Здравствуйте, derasa, Вы писали:

D>Если я вас правильно понял — то я использую устаревшие функции? Можете поделиться примером использования новых функций в контексте моей задачи?


Похоже, я наврал, по обоим пунктом, извини. Оказывается, там API уже 100 лет не обновлялось.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[4]: wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was co
От: Pavel Dvorkin Россия  
Дата: 11.07.13 09:04
Оценка:
Здравствуйте, Ops, Вы писали:

Ops>Только еще GlobalFree добавь. А вообще:


Нет, не надо там GlobalFree. Этот блок памяти переходит в собственность clipboard, его не надо удалять.

If SetClipboardData succeeds, the system owns the object identified by the hMem parameter. The application may not write to or free the data once ownership has been transferred to the system, but it can lock and read from the data until the CloseClipboard function is called.
With best regards
Pavel Dvorkin
Re[5]: wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was co
От: Ops Россия  
Дата: 11.07.13 09:22
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Нет, не надо там GlobalFree. Этот блок памяти переходит в собственность clipboard, его не надо удалять.


Да я ниже отписался, что ошибся.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[3]: wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was co
От: pugv Россия  
Дата: 11.07.13 09:42
Оценка:
Здравствуйте, derasa, Вы писали:

D>С копированием из буфера тоже проблемы. Строка с иероглифами получается. Пример взял из инета, поменял на lptstr. Что неправильно?


D>if((buf = (HGLOBAL) GetClipboardData(CF_TEXT)) != NULL)

D>{
D> lptstr = (LPTSTR)GlobalLock(buf);
D>}

Например то, что проект у Вас юникодный, соответственно LPTSTR это WCHAR*, а просите формат CF_TEXT, который возвращает в кодировке ANSI.
Re[4]: wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was co
От: derasa  
Дата: 11.07.13 11:03
Оценка:
Здравствуйте, pugv, Вы писали:

P>Здравствуйте, derasa, Вы писали:


D>>С копированием из буфера тоже проблемы. Строка с иероглифами получается. Пример взял из инета, поменял на lptstr. Что неправильно?


D>>if((buf = (HGLOBAL) GetClipboardData(CF_TEXT)) != NULL)

D>>{
D>> lptstr = (LPTSTR)GlobalLock(buf);
D>>}

P>Например то, что проект у Вас юникодный, соответственно LPTSTR это WCHAR*, а просите формат CF_TEXT, который возвращает в кодировке ANSI.


А как в таком случае быть? Как из АНСИ преобразовать в wstring?
Re[5]: wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was co
От: pugv Россия  
Дата: 11.07.13 11:28
Оценка:
Здравствуйте, derasa, Вы писали:

D>А как в таком случае быть? Как из АНСИ преобразовать в wstring?


Можно сразу попросить CF_UNICODETEXT. А преобразовать — это см. в сторону MultiByteToWideChar.
Re[6]: wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was co
От: derasa  
Дата: 11.07.13 11:57
Оценка:
Здравствуйте, pugv, Вы писали:

P>Здравствуйте, derasa, Вы писали:


D>>А как в таком случае быть? Как из АНСИ преобразовать в wstring?


P>Можно сразу попросить CF_UNICODETEXT. А преобразовать — это см. в сторону MultiByteToWideChar.


Спасибо, UNICODETEXT помогло. Сделал в итоге так:

CHAR* str = (CHAR*)GlobalLock(buf);
wstring wstr = (wstring)str;

Методологически может и не оптимально, но работает. Если не верно, буду признателен за более оптимальный вариант
Re[7]: wchar_t, wstring и буфер обмена: Stack around the variable 'curt' was co
От: pugv Россия  
Дата: 11.07.13 12:11
Оценка:
Здравствуйте, derasa, Вы писали:

D>CHAR* str = (CHAR*)GlobalLock(buf);
D>wstring wstr = (wstring)str;


Зачем лишний каст к CHAR* ?

wstring wstr((wchar_t*)GlobalLock(buf));
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.