2013-09-22 3 views
6

Я следующий блок кода:-ошибка символов чтение строки

for(CarsPool::CarRecord &record : recs->GetRecords()) 
{ 
    LVITEM item; 
    item.mask = LVIF_TEXT; 
    item.cchTextMax = 6; 

    item.iSubItem = 0; 
    item.pszText = (LPSTR)(record.getCarName().c_str()); //breakpoint on this line. 
    item.iItem = 0; 
    ListView_InsertItem(CarsListView, &item); 

    item.iSubItem = 1; 
    item.pszText = TEXT("Available"); 
    ListView_SetItem(CarsListView, &item); 

    item.iSubItem = 2; 
    item.pszText = (LPSTR)CarsPool::EncodeCarType(record.getCarType()); 
    ListView_SetItem(CarsListView, &item); 
} 

Информация из Visual Studio Debugger здесь:

enter image description here

Почему не программа способна читать символы из строки?

тест показал мне, что он работает таким образом:

MessageBox(hWnd, (LPSTR)(record.getCarName().c_str()), "Test", MB_OK); 
+1

Возвращает ли 'getCarName' копию? В этом случае временное возвращение уничтожается в конце выражения, оставляя указатель, возвращенный 'c_str()' dangling. См. [здесь] (http://stackoverflow.com/questions/4214153/lifetime-of-temporaries) – user786653

+0

Отладчик не может прочитать информацию, потому что вы все еще находитесь в точке ** до ** присвоения. '0xcccccccc' - значение, которое CRT Microsoft заполняет выделенной памятью. Если вы видите эту последовательность, у вас есть неинициализированная память. – IInspectable

+0

Мне нужна эта точка останова, потому что вывод «выглядит пустым» в моем списке. – Victor

ответ

4

getCarName Вероятно, возврат временно. После назначения временный объект уничтожается, а указатель item.pszText указывает на недопустимую память. Вы должны убедиться, что строковый объект действителен во время вызова до ListView_InsertItem.

std::string text(record.getCarName()); 
item.iSubItem = 0; 
item.pszText = const_cast<LPSTR>(text.c_str()); 
item.iItem = 0; 
ListView_InsertItem(CarsListView, &item); 

const_cast является артефактом того факта, что Windows API, использует ту же структуру для установки и извлечения информации. При вызове ListView_InsertItem структура неизменна, однако нет способа отразить это на языке.

+0

+1 это предпочтительнее использовать 'strcpy' или подобные« сырые »функции C, если элемент управления списком создает копию строки (по умолчанию это IIRC). – user786653

3

Похоже, вы пытаетесь использовать значение C++ «строка» в вызове C/Win32.

stdstring.c_str() - правильный способ сделать это.

... НО ...

Вы должны STRCPY() строка переменного темпа, а затем сделать вызов Win32 с переменной темп.

+2

@ Victor - Это зависит от человека, который отвечает, как написать ответ. Я не думаю, что этот вопрос требует правильного ответа на код (и, фактически, он должен указать код). –

Смежные вопросы