опять вопрос по c_str()
От: niki_  
Дата: 28.05.04 09:32
Оценка:
Изучаю stl и наткнулся на следующую проблему:
При преобразовании из const_char* в char* происходит
какая то ерунда, указатель p (см. код) начинает смотреть на какойто хлам в памяти

#include <iostream>
#include <string>
#include <conio.h>

class A {
public:
std::string get(void) { return "this is test"; };
};

void main (void) {
A a;
std::cout<<"result 1: "<< a.get() <<std::endl;

//// почему тут глючит ?
char *p = const_cast <char*> ( a.get().c_str() );
std::cout<<"result 2: "<< p <<std::endl;
getch();
}
Re: опять вопрос по c_str()
От: Аноним  
Дата: 28.05.04 09:42
Оценка:
Здравствуйте, niki_, Вы писали:

Используй тэги [ccode]/ [/ccode]
_>#include <iostream>
_>#include <string>
_>#include <conio.h>

_>class A {
_>public:
_>    std::string get(void) { return "this is test"; };//void в скобках не нужен,
                                                   //слава Богу, 21 век, и пишем на С++
_>};

_>void main (void) { //main должна иметь тип int () либо int (int, char **), т.е.

_>    A a;
_>    std::cout<<"result 1: "<< a.get() <<std::endl;

_>    //// почему тут глючит ?
_>    char *p = const_cast <char*> ( a.get().c_str() );//серьезная проблема!!!!!
//возвращается временный объект, по окончании полного выражения он разрушается, указатель
//инвалиден
_>    std::cout<<"result 2: "<< p <<std::endl;
_>    getch();
_>}
Re: опять вопрос по c_str()
От: Сгибатель Россия  
Дата: 28.05.04 09:43
Оценка:
Здравствуйте, niki_, Вы писали:

_>    //// почему тут глючит ?
_>    char *p = const_cast <char*> ( a.get().c_str() );
_>    std::cout<<"result 2: "<< p <<std::endl;
_>    getch();


ИМХО, в конце первого предложения временный объект уничтожается.
и во втором предложении уже используется не валидный указатель.

можно так

std::cout<<"result 2: "<< const_cast <char*>( a.get().c_str() ) <<std::endl;


а вообще по этому поводу можно посмотреть "Дизайн и эволюция C++"
Re[2]: опять вопрос по c_str()
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 28.05.04 09:54
Оценка:
Здравствуйте, Сгибатель, Вы писали:

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


С>
_>>    //// почему тут глючит ?
_>>    char *p = const_cast <char*> ( a.get().c_str() );
_>>    std::cout<<"result 2: "<< p <<std::endl;
_>>    getch();
С>


С>ИМХО, в конце первого предложения временный объект уничтожается.

С>и во втором предложении уже используется не валидный указатель.

С>можно так


С>
С>std::cout<<"result 2: "<< const_cast <char*>( a.get().c_str() ) <<std::endl;

С>


Ещё правильнее сделать так:
std::cout<<"result 2: "<< a.get() <<std::endl;


IMHO применять const_cast<char*> по отношению к результату возвращаемому из std::basic_string<_Char>::c_str() вредно, потому как в конченом итоге руки могут зачесаться этот результат использовать как lvalue в целях какой-нибудь сомнительной оптимизации, а к чему это приведёт и где это вылезет даже Страуструпу неизвестно.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re: опять вопрос по c_str()
От: Vamp Россия  
Дата: 28.05.04 09:57
Оценка:
Здесь проблема не в преобразованиях. Ты возвращаешь временный объект типы string, который удаляется после завершения выражения, в данном случае инициализации указателя p. Удаление объекта осовбождает и его буфер, после чего р указывает в неинициализированную область в памяти.
Да здравствует мыло душистое и веревка пушистая.
Re: опять вопрос по c_str()
От: Аноним  
Дата: 28.05.04 11:54
Оценка:
Здравствуйте, niki_, Вы писали:
А зачем?
const T к T лучше не преобразовать
Re[2]: опять вопрос по c_str()
От: niki_  
Дата: 28.05.04 12:19
Оценка:
Здравствуйте, Аноним, Вы писали:

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

А> А зачем?
А>const T к T лучше не преобразовать

Тьфу ... елки палки, опять на детские грабли наступил ... c временным объектом.

проблема была собсно в следующем :

В SDK для Unigraphics, под который я пишу утилиты, есть обширный
набор C функций и не очень обширный набор C++ классов.

С С++ под Unigraphics работать просто и приятно, за исключением того,
что не весь функционал C-шных есть в C++ классах.

Поэтому мой код представляет жуткий микс из C/C++ и , периодически, получив
из C++ метода std::string, например имя объекта, затем надо это имя преобразовать
в указатель на char, чтобы использовать его в С-функции, ф-ция имеет прототип типа

int do_it( char *name, int data);

от этого и происходит преобразование const T к T

Спасибо всем за ответы !

PS Лучше два раза наступить на взрослые грабли, чем один раз на детские
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.