память под объекты-исключения
От: ilejn Россия  
Дата: 27.06.05 08:52
Оценка:
Я тут рассматривал главу 14.2.1 "Производные исключение"
у Страустрапа и понял, что не понимаю одной базовой вещи.

Есть у нас, согласно книжке,
некий
class int_overflow{
const char *op;
public: int_overflow(cont char *p){op=p}
/*...*/
};
с которым мы поступаем вот так
int add()
{
/*...*/

if(/*...*/)
throw int_overflow("+");

/*...*/
}

Так вот, строка с плюсом отведена на стеке,
и когда мы попытаемся анализировать исключение,
мы обратимся к довольно странному куску стека,
который скорее свободен, чем занят.

В каком месте своих рассуждений я ошибаюсь?
Re: память под объекты-исключения
От: aik Австралия  
Дата: 27.06.05 09:08
Оценка:
Здравствуйте, ilejn, Вы писали:

I>Я тут рассматривал главу 14.2.1 "Производные исключение"

I>у Страустрапа и понял, что не понимаю одной базовой вещи.

I>Есть у нас, согласно книжке,

I>некий
I>class int_overflow{
I>const char *op;
I>public: int_overflow(cont char *p){op=p}
I>/*...*/
I>};
I>с которым мы поступаем вот так
I>int add()
I>{
I> /*...*/

I> if(/*...*/)

I> throw int_overflow("+");

I> /*...*/

I>}

I>Так вот, строка с плюсом отведена на стеке,

I>и когда мы попытаемся анализировать исключение,
I>мы обратимся к довольно странному куску стека,
I>который скорее свободен, чем занят.

I>В каком месте своих рассуждений я ошибаюсь?


Это не цепэпэ, а простой си. Строка будет не на стеке, а в сегменте данных.
Re[2]: память под объекты-исключения
От: ilejn Россия  
Дата: 27.06.05 09:13
Оценка:
Здравствуйте, aik, Вы писали:

aik>Это не цепэпэ, а простой си. Строка будет не на стеке, а в сегменте данных.


Не совсем понял это утверждение. Объясните, пожалуйста.


Ну хорошо, а если мы напишем

if(/*...*/)
{
std::string err("+");
throw int_overflow(err.c_str());
}

то это что-то изменит?
Re[3]: память под объекты-исключения
От: aik Австралия  
Дата: 27.06.05 09:53
Оценка:
Здравствуйте, ilejn, Вы писали:

aik>>Это не цепэпэ, а простой си. Строка будет не на стеке, а в сегменте данных.

I>Не совсем понял это утверждение. Объясните, пожалуйста.
I>Ну хорошо, а если мы напишем
I>if(/*...*/)
I>{
I>std::string err("+");
I>throw int_overflow(err.c_str());
I>}
I>то это что-то изменит?

Думаю, что изменит, но в данном контексте пофигу. Зависит от реализации string. Либо string будет держать в себе указатель на строку в DS (до первой попытки записи в строку), либо сразу откопирует куда то в свою память (которую выделит в динамическом хипе). В любом случае строка на стеке не окажется. Чтобы она была на стеке, ее надо либо явно там выделить конструкцией char s[32] = "+"; либо через strcpy((char*)_alloca(32), "+").
Re[4]: память под объекты-исключения
От: ilejn Россия  
Дата: 27.06.05 10:20
Оценка:
Здравствуйте, aik, Вы писали:

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


aik>>>Это не цепэпэ, а простой си. Строка будет не на стеке, а в сегменте данных.

I>>Не совсем понял это утверждение. Объясните, пожалуйста.

Уже понял

I>>Ну хорошо, а если мы напишем

I>>if(/*...*/)
I>>{
I>>std::string err("+");
I>>throw int_overflow(err.c_str());
I>>}
I>>то это что-то изменит?

aik>Думаю, что изменит, но в данном контексте пофигу. Зависит от реализации string. Либо string будет держать в себе указатель на строку в DS (до первой попытки записи в строку), либо сразу откопирует куда то в свою память (которую выделит в динамическом хипе). В любом случае строка на стеке не окажется. Чтобы она была на стеке, ее надо либо явно там выделить конструкцией char s[32] = "+"; либо через strcpy((char*)_alloca(32), "+").


Согласен. Я привел неудачный пример, но к моменту анализа
исключения op все-таки имеет все шансы указывать на уже освобожденную память,
потому что err к этому моменту уже удалился.

Мне кажется, что иметь такие объекты-исключения как int_overflow
крайне нежелательно, потому что торчащий из них указатель (или, скажем, ссылка)
может указывать на что-нибудь, что освободилось при раскрутке стека.
Действительно ли это так?
Re[2]: память под объекты-исключения
От: Николай Ганичев Россия  
Дата: 27.06.05 12:01
Оценка:
Здравствуйте, aik, Вы писали:

aik>Это не цепэпэ, а простой си. Строка будет не на стеке, а в сегменте данных.


Простой С с исключениями, ага. Приехали, называется.

В том, что строка будет не на стеке, Вы правы. Но по другой причине. В соответствии с пунктом 2.13.4/1 стандарта С++, string literals имеют static storage duration. Так-что приведённый код безопасен, но на мой взгляд — сомнителен.
... << RSDN@Home 1.1.4 beta 7 rev. 463>>
Re[3]: память под объекты-исключения
От: aik Австралия  
Дата: 27.06.05 12:14
Оценка:
Здравствуйте, Николай Ганичев, Вы писали:

aik>>Это не цепэпэ, а простой си. Строка будет не на стеке, а в сегменте данных.

НГ>Простой С с исключениями, ага. Приехали, называется.

имелось ввиду, что вопрос про размещение строк на стеке относится не к cpp, а к простому си.
Re[4]: память под объекты-исключения
От: Николай Ганичев Россия  
Дата: 27.06.05 12:37
Оценка:
Здравствуйте, aik, Вы писали:

aik>>>Это не цепэпэ, а простой си. Строка будет не на стеке, а в сегменте данных.

НГ>>Простой С с исключениями, ага. Приехали, называется.
aik>имелось ввиду, что вопрос про размещение строк на стеке относится не к cpp, а к простому си.

Размещение строковых литералов в С++ описывается стандартом С++. То, что оно совместимо с Си и в какой степени — вопрос десятый.
... << RSDN@Home 1.1.4 beta 7 rev. 463>>
Re[4]: память под объекты-исключения
От: MaximE Великобритания  
Дата: 27.06.05 13:03
Оценка:
aik wrote:

[]

> Думаю, что изменит, но в данном контексте пофигу. Зависит от реализации string. Либо string будет держать в себе указатель на строку в DS (до первой попытки записи в строку), либо сразу откопирует куда то в свою память (которую выделит в динамическом хипе). В любом случае строка на стеке не окажется. Чтобы она была на стеке, ее надо либо явно там выделить конструкцией char s[32] = "+"; либо через strcpy((char*)_alloca(32), "+").


STLPort и Dinkum применяют small string optimization — строки до определенного размера храняться в буфере в объекте строки, а не в динамической памяти.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.