char * и с чем его едят;
От: Аноним  
Дата: 21.09.03 15:49
Оценка:
Помогите, новичку, пожалуйста:

В следующем коде происходит ссылка на массив чаров из Memo? где они храниятся и как?

static char *text;
text=Form1->Memo1->Lines->Text;

тогда почему поле данного кода происходит потеря данных(вмысле text ссылается на что-то другое)?

int SIZE_TEG=NULL;
int BEGIN_TEG=NULL;
int END_TEG=NULL;
while(!(text[POSITION]=='\0'))
{

if (text[POSITION]=='<')
{
BEGIN_TEG=(POSITION+1);
while(!(text[POSITION]=='>'))
{
POSITION++;
}
END_TEG=POSITION;

//////////////////

int COUNT_TAG=NULL;
SIZE_TAG=((END_TEG-BEGIN_TEG)+1);

char *t_text;
t_text=new char[SIZE_TAG];
for (int POSITION_TEG=BEGIN_TEG;POSITION_TEG<END_TEG;POSITION_TEG++)
{
t_text[COUNT_TAG]=text[POSITION_TEG];
COUNT_TAG++;
}
while (!(COUNT_TAG==SIZE_TAG))
{
t_text[COUNT_TAG]='\0';
COUNT_TAG++;
}
COUNT_TAG=NULL;

return(*t_text);
///////////////////

}

POSITION++;

}

В чём я не прав, может быть во всём?
Re: char * и с чем его едят;
От: Аноним  
Дата: 21.09.03 15:51
Оценка: -1
Здравствуйте, Аноним, Вы писали:

А>Помогите, новичку, пожалуйста:


А>В следующем коде происходит ссылка на массив чаров из Memo? где они храниятся и как?


А>static char *text;

А>text=Form1->Memo1->Lines->Text;
text=Form1->Memo1->Lines->Text.c_str();// точнее так

А>тогда почему поле данного кода происходит потеря данных(вмысле text ссылается на что-то другое)?


А> int SIZE_TEG=NULL;

А> int BEGIN_TEG=NULL;
А> int END_TEG=NULL;
А> while(!(text[POSITION]=='\0'))
А> {

А> if (text[POSITION]=='<')

А> {
А> BEGIN_TEG=(POSITION+1);
А> while(!(text[POSITION]=='>'))
А> {
А> POSITION++;
А> }
А> END_TEG=POSITION;

А> //////////////////


А> int COUNT_TAG=NULL;

А> SIZE_TAG=((END_TEG-BEGIN_TEG)+1);

А> char *t_text;

А> t_text=new char[SIZE_TAG];
А> for (int POSITION_TEG=BEGIN_TEG;POSITION_TEG<END_TEG;POSITION_TEG++)
А> {
А> t_text[COUNT_TAG]=text[POSITION_TEG];
А> COUNT_TAG++;
А> }
А> while (!(COUNT_TAG==SIZE_TAG))
А> {
А> t_text[COUNT_TAG]='\0';
А> COUNT_TAG++;
А> }
А> COUNT_TAG=NULL;

А> return(*t_text);

А> ///////////////////

А> }


А> POSITION++;


А> }


А>В чём я не прав, может быть во всём?
Re[2]: char * и с чем его едят;
От: ArtDenis Россия  
Дата: 21.09.03 16:28
Оценка:
Здравствуйте, <Аноним>, Вы писали:
А> text=Form1->Memo1->Lines->Text.c_str();// точнее так

Ни в коем случае нельзя так делать. c_str() возвращает указатель на временный буффер. c_str() млжно использовать для передачи в функции:


void func(const char *text)
{
  //...
}
func( Form1->Memo1->Lines->Text.c_str() );


Для копирования в массив char'ов лучше пользоваться вот этим:

char *data;
data = new[Form1->Memo1->Lines->Text.Length()+1]  
strcpy( data, Form1->Memo1->Lines->Text.c_str() );

// работаем с data
// ....

// удаляем data:
delete[] data; data = NULL;


Кроме того, не рекомендую возвращать, char* в качестве результата функции (из-за соображений потокобезопасности). Для этого используй контейнеры для строк: AnsiString, std::string

Денис.
... << RSDN@Home 1.1 beta 1 >>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[3]: char * и с чем его едят;
От: Аноним  
Дата: 21.09.03 17:08
Оценка:
Ок,спасибо
Re[3]: char * и с чем его едят;
От: SWW Россия  
Дата: 22.09.03 04:35
Оценка:
А>> text=Form1->Memo1->Lines->Text.c_str();// точнее так

AD>Ни в коем случае нельзя так делать. c_str() возвращает указатель на временный буффер.


Когда-то я писал о вредности оператора c_str(),
Автор: SWW
Дата: 24.07.03
однако читатели со мной не согласились и наставили мне минусов. Вы и сейчас считаете, что я не прав?
Re[4]: char * и с чем его едят;
От: ArtDenis Россия  
Дата: 22.09.03 05:51
Оценка:
Здравствуйте, SWW, Вы писали:

А>>> text=Form1->Memo1->Lines->Text.c_str();// точнее так


AD>>Ни в коем случае нельзя так делать. c_str() возвращает указатель на временный буффер.


SWW>Когда-то я писал о вредности оператора c_str(),
Автор: SWW
Дата: 24.07.03
однако читатели со мной не согласились и наставили мне минусов. Вы и сейчас считаете, что я не прав?


По-моему, минус тебе за другое поставили.
... << RSDN@Home 1.1 beta 1 >>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[3]: char * и с чем его едят;
От: Кодт Россия  
Дата: 22.09.03 06:08
Оценка: +2
Здравствуйте, ArtDenis, Вы писали:

AD>Для копирования в массив char'ов лучше пользоваться вот этим:


AD>
AD>char *data;
AD>data = new[Form1->Memo1->Lines->Text.Length()+1]  
AD>strcpy( data, Form1->Memo1->Lines->Text.c_str() );

AD>// работаем с data
AD>// ....

AD>// удаляем data:
AD>delete[] data; data = NULL;

AD>


Специально для этого, в ANSI C в составе <string.h>:
char* data;
data = strdup(SomethingReturningString());
// эквивалентно: data = strcpy(malloc(strlen(source)), source)
...
free(data):
Перекуём баги на фичи!
Re[4]: char * и с чем его едят;
От: Аноним  
Дата: 22.09.03 06:23
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Специально для этого, в ANSI C в составе <string.h>:

К>
К>char* data;
К>data = strdup(SomethingReturningString());
К>// эквивалентно: data = strcpy(malloc(strlen(source)), source)
К>...
К>free(data):
К>


Это с каких же пор strdup стало ANSI???
Re[3]: char * и с чем его едят;
От: Vamp Россия  
Дата: 22.09.03 07:10
Оценка:
AD>Кроме того, не рекомендую возвращать, char* в качестве результата функции (из-за соображений потокобезопасности). Для этого используй контейнеры для строк: AnsiString, std::string

Когда это у нас std::string стал потокобезопасным?
Да здравствует мыло душистое и веревка пушистая.
Re[4]: char * и с чем его едят;
От: Sergeem Израиль  
Дата: 22.09.03 07:21
Оценка:
Здравствуйте, SWW, Вы писали:

А>>> text=Form1->Memo1->Lines->Text.c_str();// точнее так


AD>>Ни в коем случае нельзя так делать. c_str() возвращает указатель на временный буффер.


SWW>Когда-то я писал о вредности оператора c_str(),
Автор: SWW
Дата: 24.07.03
однако читатели со мной не согласились и наставили мне минусов. Вы и сейчас считаете, что я не прав?



Да если программист не понимает, почему так писать нельзя, то ему это все равно не поможет, прочтиав сообщение компилятора об ошибке он быстро исправится и напишет:
const char* ps = (s1 + s2).c_str();


Вот так и получаются висячие поинтеры!

А с_str() нужен имхо для совместимости: когда вместо std::string нужно передать const char*.
Например, fstream принимает в кач-ве параметра (почему-то?) const char*.
Serge.

Hасколько проще была бы жизнь, если бы она была в исходниках.
Re[5]: char * и с чем его едят;
От: Vamp Россия  
Дата: 22.09.03 07:25
Оценка:
S>

S>Да если программист не понимает, почему так писать нельзя, то ему это все равно не поможет, прочтиав сообщение компилятора об ошибке он быстро исправится и напишет:
S>const char* ps = (s1 + s2).c_str();


S>Вот так и получаются висячие поинтеры!

Не могу понять логику в таком написании. c_str() вообще не предназначен для того, чтобы его результат где-то сохранялся.
Да здравствует мыло душистое и веревка пушистая.
Re[4]: char * и с чем его едят;
От: ArtDenis Россия  
Дата: 22.09.03 07:31
Оценка:
Здравствуйте, Vamp, Вы писали:

AD>> Кроме того, не рекомендую возвращать, char* в качестве результата

AD>> функции (из-за соображений потокобезопасности). Для этого используй
AD>> контейнеры для строк: AnsiString, std::string
V> Когда это у нас std::string стал потокобезопасным?

Уточню:
AD>>...не рекомендую возвращать, char*, полученный от c_str()
AD>>в качестве результата функции в любом случае....

Кроме того, если ты используешь в разных потоках функцию, возвращающую
std::string, то проблем с потокобезопасностью не будет, т.к. возвращаемые
объекты работают с различающмися наборами данных. Когда ты работаешь с
c_str(), есть вероятность того, что буфер, возвращаемый c_str — статический.
Тогда вызов c_str() одновременно из двух потоков приведёт к плачевному
результату.

---------------------------------------------------------
СНП, Artyomov Denis. E-mail: artyomov <at> inbox.ru
Posted via RSDN NNTP Server 1.7 beta
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[5]: char * и с чем его едят;
От: SWW Россия  
Дата: 22.09.03 08:43
Оценка:
А>>>> text=Form1->Memo1->Lines->Text.c_str();// точнее так

AD>>>Ни в коем случае нельзя так делать. c_str() возвращает указатель на временный буффер.


S>

S>Да если программист не понимает, почему так писать нельзя, то ему это все равно не поможет, прочтиав сообщение компилятора об ошибке он быстро исправится и напишет:
S>const char* ps = (s1 + s2).c_str();


S>Вот так и получаются висячие поинтеры!


Вероятно мне следовало слово "исправится" взять в кавычки, чтобы абзацы, вырванные из контекста, оставались понятными.

S>А с_str() нужен имхо для совместимости: когда вместо std::string нужно передать const char*.

S>Например, fstream принимает в кач-ве параметра (почему-то?) const char*.

Речь шла не о том, нужна эта функция или нет, а о том, что вместо нее std::string должен иметь operator(const char*). Тогда везде, где требуется const char* можно было бы писать саму строку. Но Страуструп, помешанный на безопасности, решил, что программист может по ошибке написать const char* ps = s1 + s2, в результате чего возникнет, как ты выражаешься, висячий пойнтер. Я же писал, что наличие функции c_str() ничем не поможет программисту. И исходное письмо является подтверждением этого: его автор ошибся так же, как если бы у std::string был operator(const char*) вместо функции c_str().
Re[6]: char * и с чем его едят;
От: Павел Кузнецов  
Дата: 22.09.03 09:00
Оценка:
Здравствуйте, SWW, Вы писали:

S> Речь шла не о том, нужна эта функция или нет, а о том, что вместо нее

S> std::string должен иметь operator(const char*). Тогда везде, где
S> требуется const char* можно было бы писать саму строку.

Если бы operator const char*() const "включала" только преобразование к const char*, было бы еще
более-менее терпимо... Однако наличие operator const char*() const позволяет, например, такие вещи:

string s1 = "abcd";
string s2 = s1 + 10;


плюс делает использование многих других "нормальных" перегруженных операций более трудным, чем в случае,
когда это преобразование "выключено".
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[7]: char * и с чем его едят;
От: SWW Россия  
Дата: 22.09.03 10:19
Оценка: 1 (1)
ПК>Если бы operator const char*() const "включала" только преобразование к const char*, было бы еще
ПК>более-менее терпимо... Однако наличие operator const char*() const позволяет, например, такие вещи:

ПК>
ПК>string s1 = "abcd";
ПК>string s2 = s1 + 10;
ПК>


Наличие operator+(char) делает последнюю строку двусмысленной при наличии operator(const char*) и не позволяет ее оттранслировать.
Re[8]: char * и с чем его едят;
От: Павел Кузнецов  
Дата: 22.09.03 10:55
Оценка:
Здравствуйте, SWW, Вы писали:

ПК>>
ПК>> string s1 = "abcd";
ПК>> string s2 = s1 + 10;
ПК>>


S> Наличие operator+(char) делает последнюю строку двусмысленной при

S> наличии operator(const char*) и не позволяет ее оттранслировать.

Да, верно. Также перестанут транслироваться, например, такие вещи:

s1[10]; // ambiguous, т.к. operator[] требует size_type
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[9]: char * и с чем его едят;
От: SWW Россия  
Дата: 22.09.03 11:26
Оценка:
ПК>Да, верно. Также перестанут транслироваться, например, такие вещи:

ПК>
ПК>s1[10]; // ambiguous, т.к. operator[] требует size_type
ПК>


Не понял, это почему еще?
Re[10]: char * и с чем его едят;
От: Павел Кузнецов  
Дата: 22.09.03 11:47
Оценка:
Здравствуйте, SWW, Вы писали:

ПК>> Да, верно. Также перестанут транслироваться, например, такие вещи:


ПК>>
ПК>> s1[10]; // ambiguous, т.к. operator[] требует size_type
ПК>>


S> Не понял, это почему еще?


Потому что возможны две трактовки этого выражения в присутствии operator const char*() const:
s1.operator[](size_type(10));

и:
s1.operator const char*()[10];

Компилятор не может отдать предпочтение ни одной из них:
class string
{
public:
  operator const char*() const;
  char operator [](unsigned int) const;
};

int main()
{
  string s;
  s[10];
}

E:\users\pavel\test\string_conv>como -c test.cpp
Comeau C/C++ 4.3.0.1 (Aug 21 2002 15:45:32) for MS_WINDOWS_x86
Copyright 1988-2002 Comeau Computing.  All rights reserved.
MODE:strict warnings C++

"test.cpp", line 11: error: more than one operator "[]" matches these operands:
            built-in operator "pointer-to-object[integer]"
            function "string::operator[](unsigned int) const"
            operand types are: string [ int ]
    s[10];
     ^

1 error detected in the compilation of "test.cpp".
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[11]: char * и с чем его едят;
От: SWW Россия  
Дата: 22.09.03 12:50
Оценка:
ПК>class string
ПК>{
ПК>public:
ПК> operator const char*() const;
ПК> char operator [](unsigned int) const;
ПК>};

Ты хочешь убедить меня в том, что operator const char*() в std::string отсутствует потому, что это невозможно реализовать? При желании сделать можно все, например заменить unsigned int на int. Но дело-то не в этом, а в том, что это не было сделано специально, для повышения такназываемой "безопасности", о чем и пишет Страуструп.
Re[12]: char * и с чем его едят;
От: Павел Кузнецов  
Дата: 22.09.03 13:05
Оценка:
Здравствуйте, SWW, Вы писали:

S> Ты хочешь убедить меня в том, что operator const char*() в

S> std::string отсутствует потому, что это невозможно реализовать?

Нет. Просто его наличие приводит к большему количеству неприятностей, чем его отсутствие.

S> При желании сделать можно все, например заменить unsigned int на int.


Тогда будут проблемы с int. Если добавить и int, и unsigned, будут проблемы с long.
В общем, перегружать operator[] придется со всеми встроенными типами.

S> Но дело-то не в этом, а в том, что это не было сделано специально, для

S> повышения такназываемой "безопасности", о чем и пишет Страуструп.

Нарушение безопасности типов — одна из добавляющихся неприятностей, но не единственная.
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.