Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума? / 25 сообщений из 34, страница 1 из 2
15.02.2017, 01:01
    #39404528
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
Господа!

Что такого криминального в такой конструкции:
Код: plaintext
1.
2.
char *ch = Edit1->Text.c_str(); // В дизайнере сидит текст по умолчанию "Edit1"
ShowMessage(ch); // !!! Получаю "Edit" !!!


Строка просто обрезается!

Почему?!

При этом:
Код: plaintext
1.
2.
3.
AnsiString str = Edit1->Text; 
char *ch = str.c_str(); // В дизайнере сидит текст по умолчанию "Edit1"
ShowMessage(ch); // Получаю "Edit1"

- всё нормально.

Мистико?

P.S. Builder 6.
...
Рейтинг: 0 / 0
15.02.2017, 02:04
    #39404534
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
НубикКонкретныйP.S. Builder 6.
Слишком новая версия, ещё не успели баги исправить.
...
Рейтинг: 0 / 0
15.02.2017, 06:46
    #39404550
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
НубикКонкретный,

почитай про динамическое выделение памяти и все из рода "Мистико" уйдут сами собой
...
Рейтинг: 0 / 0
15.02.2017, 08:02
    #39404567
CEMb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
kealon(Ruslan), тут же нету динамического выделения памяти

в первом случае берётся указатель на родную строку
во втором случае сначала строка копируется в новый объект, потом берётся указатель с неё.
странно, что компилятор не ругается на char*, должен хотеть const char*, иначе ub
...
Рейтинг: 0 / 0
15.02.2017, 10:21
    #39404613
teo609
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
Предположу, что Edit1->Text возвращает временный объект (удаляется в конце выражения, т.е. встретив ";").
Тогда во втором случае он сохраняется в str, а в первом удаляется.
Поэтому во втором случае ch указывает на память объекта str, а в первом на память удаленного объекта, т.е. на случайную область памяти. То, что там "Edit" - совпадение. Обрезаться строке не с чего.
...
Рейтинг: 0 / 0
15.02.2017, 10:23
    #39404615
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
НубикКонкретныйГоспода!

Что такого криминального в такой конструкции:
Код: plaintext
1.
2.
char *ch = Edit1->Text.c_str(); // В дизайнере сидит текст по умолчанию "Edit1"
ShowMessage(ch); // !!! Получаю "Edit" !!!


Строка просто обрезается!

Почему?!

При этом:
Код: plaintext
1.
2.
3.
AnsiString str = Edit1->Text; 
char *ch = str.c_str(); // В дизайнере сидит текст по умолчанию "Edit1"
ShowMessage(ch); // Получаю "Edit1"

- всё нормально.

Мистико?

P.S. Builder 6.

понятие точки следования тебе знакомо?
я не уверен, что дело именно в этом, но по крайней мере может быть в ней.
...
Рейтинг: 0 / 0
15.02.2017, 10:27
    #39404618
ну я
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
НубикКонкретный,

Edit1->Text.c_str();
Здесь выражение Edit1->Text возвращает объект AnsiString.
Этот объект временный.

char *ch = Edit1->Text.c_str();
Тут от него берется указатель на некие его внутренние потроха.

После выполнения оператора присваивания
char *ch = ...
этот временный объект не используется, char *ch указывает на потроха мусора.

ShowMessage(ch);
Тут используется этот самый указатель на северо-юг.

Что тут криминального - судить автору, смотря чего он считает правильным, но компилятор исполняет то что ему предписано исполнить.

char* ch это не строка)))), это указатель на саму строку ))))
...
Рейтинг: 0 / 0
15.02.2017, 12:37
    #39404789
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
И вправду. Долбаные проперти.

Код: plaintext
1.
2.
3.
AnsiString str = Edit1->Text; 
/// в этой точке вызывается деструктор временной строки
char *ch = str.c_str(); 


надо так
Код: plaintext
1.
ShowMessage(edName->Text); // и сразу именовать контролы нормально! зарубить на носу
...
Рейтинг: 0 / 0
15.02.2017, 15:28
    #39405015
ну я
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
НубикКонкретный
Код: plaintext
1.
2.
3.
AnsiString str = Edit1->Text; 
char *ch = str.c_str(); // В дизайнере сидит текст по умолчанию "Edit1"
ShowMessage(ch); // Получаю "Edit1"

- всё нормально.

Формально говоря, это тоже ненормально, потому что после взятия char *ch = ... сам объект str уже не используется.
Возможно, используется дальше по реальному коду откуда было взято, но в приведенном фрагменте - нет.
Корректно так:

ShowMessage(str);

или

ShowMessage(str.c_str());

Или сделать фейковую функцию использования

void fake_use(void*p){};

AnsiString str = Edit1->Text;
char *ch = str.c_str();
ShowMessage(ch);
fake_use(&str);

Это требование компилятору чтобы он гарантированно держал объект str живым в течении выполнения ShowMessage.
...
Рейтинг: 0 / 0
15.02.2017, 16:43
    #39405113
Вася Уткин
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
ну яНубикКонкретный
Код: plaintext
1.
2.
3.
AnsiString str = Edit1->Text; 
char *ch = str.c_str(); // В дизайнере сидит текст по умолчанию "Edit1"
ShowMessage(ch); // Получаю "Edit1"

- всё нормально.

Формально говоря, это тоже ненормально, потому что после взятия char *ch = ... сам объект str уже не используется.
Возможно, используется дальше по реальному коду откуда было взято, но в приведенном фрагменте - нет.
Корректно так:

ShowMessage(str);

или

ShowMessage(str.c_str());

Или сделать фейковую функцию использования

void fake_use(void*p){};

AnsiString str = Edit1->Text;
char *ch = str.c_str();
ShowMessage(ch);
fake_use(&str);

Это требование компилятору чтобы он гарантированно держал объект str живым в течении выполнения ShowMessage.
Во, спасибо, объяснили! А иначе сборщик мусора удалит str раньше окончания code-scope, или кто?
...
Рейтинг: 0 / 0
15.02.2017, 18:35
    #39405207
ну я
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
Вася УткинА иначе сборщик мусора удалит str раньше окончания code-scope, или кто?
В С++ нет сборщика мусора, в нем компилятор вызывает деструкторы, когда объект либо выходит из области видимости либо когда компилятор видит что он не нужен, но со вторым вариантом ситуация неоднозначна, на усмотрение компилятора. А использованная им память может быть потерта внутренними служебными операциями или другими объектами, или кем-то из других потоков.

В принципе, возможен код, который корректно работает но при очередной сборке взял и перестал:

{
TLockObject lock(resource)
операции с лоченым ресурсом
}
где конструктор ставит и деструктор снимает блокировку.

Тут компилятор может как удержать объект lock до конца блока {} так и убить перед первым же оператором после объявления TLockObject lock.

В общем, критерий всех тестеров "а у меня работает" еще не критерий корректности для программистов, оно может и перестать работать при очередной компиляции ))))
...
Рейтинг: 0 / 0
15.02.2017, 18:39
    #39405213
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
ну яВася УткинА иначе сборщик мусора удалит str раньше окончания code-scope, или кто?
В С++ нет сборщика мусора, в нем компилятор вызывает деструкторы, когда объект либо выходит из области видимости либо когда компилятор видит что он не нужен, но со вторым вариантом ситуация неоднозначна, на усмотрение компилятора....
Про второй вариант врешь. Его нет, все там однозначно.
...
Рейтинг: 0 / 0
15.02.2017, 19:10
    #39405224
Вася Уткин
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
ну яВася УткинА иначе сборщик мусора удалит str раньше окончания code-scope, или кто?
В С++ нет сборщика мусора, в нем компилятор вызывает деструкторы, когда объект либо выходит из области видимости либо когда компилятор видит что он не нужен, но со вторым вариантом ситуация неоднозначна, на усмотрение компилятора. А использованная им память может быть потерта внутренними служебными операциями или другими объектами, или кем-то из других потоков.

В принципе, возможен код, который корректно работает но при очередной сборке взял и перестал:

{
TLockObject lock(resource)
операции с лоченым ресурсом
}
где конструктор ставит и деструктор снимает блокировку.

Тут компилятор может как удержать объект lock до конца блока {} так и убить перед первым же оператором после объявления TLockObject lock.

В общем, критерий всех тестеров "а у меня работает" еще не критерий корректности для программистов, оно может и перестать работать при очередной компиляции ))))
Т.е. в C++11 объекты RAII-блокировок std::unique_lock и std::lock_guard не гарантируют, что они будут существовать до конца code-scope, т.е. могут в любой момент быть уничтожены и следующий код не гарантирует потоко-безопасность и правильную работу?
Вы пробовали связаться с комитетом по стандартизации C++ и объяснить Страуструпу, что предлагаемый им принцип RAII-в общем не работает?
http://en.cppreference.com/w/cpp/thread/lock_guard
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
#include <thread>
#include <mutex>
#include <iostream>
 
int g_i = 0;
std::mutex g_i_mutex;  // protects g_i
 
void safe_increment()
{
    std::lock_guard<std::mutex> lock(g_i_mutex);
    ++g_i;
 
    std::cout << std::this_thread::get_id() << ": " << g_i << '\n';
 
    // g_i_mutex is automatically released when lock
    // goes out of scope
}
 
int main()
{
    std::cout << __func__ << ": " << g_i << '\n';
 
    std::thread t1(safe_increment);
    std::thread t2(safe_increment);
 
    t1.join();
    t2.join();
 
    std::cout << __func__ << ": " << g_i << '\n';
}
...
Рейтинг: 0 / 0
15.02.2017, 21:07
    #39405276
ну я
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
Вася УткинТ.е. в C++11 объекты RAII-блокировок std::unique_lock и std::lock_guard не гарантируют, что они будут существовать до конца code-scope, т.е. могут в любой момент быть уничтожены и следующий код не гарантирует потоко-безопасность и правильную работу?
Вы пробовали связаться с комитетом по стандартизации C++ и объяснить Страуструпу, что предлагаемый им принцип RAII-в общем не работает?
[/src]
Про С++ 11 не в курсе, пользуюсь более старыми компиляторами, на них выскакивали такие неприятности. Логически - да, могут быть уничтожены и не гарантируют. Нет, связываться не пробовал. Со Страуструпом не общался. Да, принцип в общем случае не работает, если компиляторы могут вызвать деструктор раньше чем объект покинет область видимости. Ну, может возьмут и строго отнесутся к времени жизни объектов, и компиляторы поддержат, тогда будет и принцип работать. Проблем-то...
...
Рейтинг: 0 / 0
15.02.2017, 21:43
    #39405293
ну я
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
Siemarglну япропущено...

В С++ нет сборщика мусора, в нем компилятор вызывает деструкторы, когда объект либо выходит из области видимости либо когда компилятор видит что он не нужен, но со вторым вариантом ситуация неоднозначна, на усмотрение компилятора....
Про второй вариант врешь. Его нет, все там однозначно.
Да я тоже полагался на то, что его в языке нет, и заложился на красивый код, однако между "компилятор может" и "компилятор по стандарту должен" обнаружилась одна большая и неприятная разница, об чем и высказался. Нет, не вру, на самом деле был такой реальный случай )))
...
Рейтинг: 0 / 0
15.02.2017, 22:11
    #39405304
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
ну яSiemarglпропущено...

Про второй вариант врешь. Его нет, все там однозначно.
Да я тоже полагался на то, что его в языке нет, и заложился на красивый код, однако между "компилятор может" и "компилятор по стандарту должен" обнаружилась одна большая и неприятная разница, об чем и высказался. Нет, не вру, на самом деле был такой реальный случай )))

есть такая частая ошибка - забыть указать переменную, объект создаётся и удаляется тут же
но если указать, то вроде как по стандарту вызов деструктора в конце блока видимости должен быть


микрософт по этому поводу пишет

PS: в реальности, наверное, лучше стараться избегать таких вещей
...
Рейтинг: 0 / 0
16.02.2017, 00:51
    #39405354
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
ну яSiemarglпропущено...

Про второй вариант врешь. Его нет, все там однозначно.
Да я тоже полагался на то, что его в языке нет, и заложился на красивый код, однако между "компилятор может" и "компилятор по стандарту должен" обнаружилась одна большая и неприятная разница, об чем и высказался. Нет, не вру, на самом деле был такой реальный случай )))а что за компилятор был?
...
Рейтинг: 0 / 0
16.02.2017, 08:43
    #39405422
ну я
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
egorychну япропущено...

Да я тоже полагался на то, что его в языке нет, и заложился на красивый код, однако между "компилятор может" и "компилятор по стандарту должен" обнаружилась одна большая и неприятная разница, об чем и высказался. Нет, не вру, на самом деле был такой реальный случай )))а что за компилятор был?
msvc 2005
C++ Builder 5
Оба выдали такие фокусы. То корректно собирают, то с притопами-прихлопами. Пришлось принуждать удерживать объекты. Гимору добавляло то, что это реально были блокировки, многозадачка, и код вроде чистый. Отлаживаться и выискивать проблему было тяжко, но шишку набил прочную ))))
...
Рейтинг: 0 / 0
16.02.2017, 10:47
    #39405526
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
ну я,

а на каком ни будь тестовом примере повторялось?
...
Рейтинг: 0 / 0
16.02.2017, 12:00
    #39405604
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
ну яegorychпропущено...
а что за компилятор был?
msvc 2005
C++ Builder 5
Оба выдали такие фокусы. То корректно собирают, то с притопами-прихлопами. Пришлось принуждать удерживать объекты. Гимору добавляло то, что это реально были блокировки, многозадачка, и код вроде чистый. Отлаживаться и выискивать проблему было тяжко, но шишку набил прочную ))))В многозадачке трудно отлаживаться - вечно путаешься, в каком потоке твои объекты.
Так что я не грешил бы на базовую функциональность компилятора.
...
Рейтинг: 0 / 0
16.02.2017, 13:02
    #39405642
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
Siemarglну япропущено...

В С++ нет сборщика мусора, в нем компилятор вызывает деструкторы, когда объект либо выходит из области видимости либо когда компилятор видит что он не нужен, но со вторым вариантом ситуация неоднозначна, на усмотрение компилятора....
Про второй вариант врешь. Его нет, все там однозначно.

Есть случай продления времени жизни временного объекта инициализацией им константной ссылки на объект.
Видимо, это имелось в виду.
И это почти что сборщик мусора, но такой мааааленький-маааленький...
...
Рейтинг: 0 / 0
16.02.2017, 13:35
    #39405673
ну я
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
kealon(Ruslan)ну я,

а на каком ни будь тестовом примере повторялось?
Дык именно и купился на то, что красивый код, и на тестах везде работал на ура, потому и использовал.
...
Рейтинг: 0 / 0
16.02.2017, 13:38
    #39405680
ну я
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
SiemarglВ многозадачке трудно отлаживаться - вечно путаешься, в каком потоке твои объекты.
Так что я не грешил бы на базовую функциональность компилятора.
Ок, учту, что Siemargl не хочет грешить, потому что путается в многозадачности и многопоточности. А я так и не прочь погрешить на них иной раз, баги же правят в них неспроста...
...
Рейтинг: 0 / 0
16.02.2017, 14:10
    #39405741
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
ну я,

В 100% известных мне случаях (а их было множество) когда кто-то писал что нашел баг в компиляторе, это в итоге оказывалось криворукостью программиста. А если еще и нет конкретного примера кода, то тут даже и думать нечего

Хотя конечно баги в компиляторах бывают. Но не такие, как неработающий RAII.
Например в vs2005 в std::stringstream была утечка памяти. Но это в библиотеке, а не в самом компиляторе.
...
Рейтинг: 0 / 0
16.02.2017, 14:43
    #39405788
ну я
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума?
Anatoly Moskovskyну я,

В 100% известных мне случаях (а их было множество) когда кто-то писал что нашел баг в компиляторе, это в итоге оказывалось криворукостью программиста. А если еще и нет конкретного примера кода, то тут даже и думать нечего

Хотя конечно баги в компиляторах бывают. Но не такие, как неработающий RAII.
У меня несколько лет был точно такой же эпизод в жизни. Он прошел ))).
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Преобразование AnsiString в char - кто из нас двоих (билдер или я) сошел с ума? / 25 сообщений из 34, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]