[VS.NET 2003 7.1.3088] Парадокс или ошибка?

Vladislav177Rus

Новый проект > С++ > Win32 Application > Empty project
Добавить > новый С++ файл
Вставить:
#include <windows.h>
#include <string>

using namespace std;

int MsgBox(LPCSTR str){
return MessageBox(0, str, "STL string test", MB_ICONASTERISK);
}

LPCSTR lpcstr(string s){
LPCSTR x = (LPCSTR)s.c_str;
MsgBox(x);
return x;
}

int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow){
string s = "Hello, world!";
MsgBox(lpcstr(s;
return 0;
}
Проделать аналогичные действия в VC++ 6
Запустить.
VS.NET: выдается окно с мсгбоксом

затем

VC++ 6:
Два раза

Поддается ли это разумному объяснению?

Dasar

У тебя стек портится:
Здесь возвращается ссылка на переменную s, которая будет удалена при выходе из функции lpcstr

LPCSTR x = (LPCSTR)s.c_str;
MsgBox(x);
return x;

Vladislav177Rus

Т.е. строка, создающаяся в .c_str адрес которой помещается в x, а потом в EAX, удаляется при выходе из функции? А как s узнает о том, что я выхожу из функции, там есть аналог AddRef-Release, который говорит, что ссылок на эту строку 0, когда происходит выход из области видимости x?

Dasar

c_str возвращает указатель на буфер внутри s, соответственно пока живет s живет и возвращенный поинтер
s у тебя уничтожается при выходе из lpcstr
У тебя две разные s.
Одна в WinMain-е и одна в lpcstr
при вызове lpcstr происходит копирование первой s во вторую.
при выходе из lpcstr вторая s уничтожается.
ps
если изменить заголовок функции lpcstr на
LPCSTR lpcstr(string& s)
то копирования с последующим уничтожением происходить не будет.

Vladislav177Rus

Ага. Понятно. А почему работает в VC6? Память остается нетронутой?

Dasar

> А почему работает в VC6? Память остается нетронутой?
Повезло. Освобожденную память никто не успел переписать.

freezer

по-моему в отладочной версии и в случае VS6 память должна затираться...
P.S. только надо <crtdbg.h> подрубить вроде. В MFC-проектах это автоматом делается

rosali

А почему работает в VC6?
Ну у разных студий же разные STL-и. Можно представить себе реализацию std::string, которая размещает c_str в статической памяти, тогда она будет валидна до следующего вызова c_str у какой-нибудь другой строки.

Julie16

А вот говорят что Both data and c_str are owned by the string.

rosali

Ну и что? Имеется в виду, что без твоего участия об этой памяти позаботятся. А как позаботятся, это уже на усмотрение реализации. И вообще не ясно string в данном случае класс или объект
Оставить комментарий
Имя или ник:
Комментарий: