Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > cout,cin


Автор: Vassik 21.2.2006, 15:43
Короче такой вот простенький код в консолевском режиме в Builder -е

int main(int argc, char* argv[])
{char *ch;
//int a;
cin >>ch;
cout << ch;
return 0;
}
Все работает замечательноsmile
Как только раскоментируем переменную ,а вообщем даже неважно какого она типа, то появляется ошибка доступа: "Access violation at adress 32657C73. Write to address 00000001 "
Возможно мой вопрос покажится забавным, но просто не пойму в чем причина, может кто объяснит мне почему возникает такая ошибка?

Автор: Romikgy 21.2.2006, 15:59
Цитата(Vassik @ 21.2.2006, 14:43 Найти цитируемый пост)
char *ch;

А выделять память под переменную кто будет?

Автор: _hunter 21.2.2006, 15:59
ошибка в том, что ты память под ch не выделяеш

Автор: DeadMan83 21.2.2006, 16:09
Глюк компилятора Borland, визуалка такое сразу не пропускает.

Автор: Romikgy 21.2.2006, 16:25
Код

int main(int argc, char* argv[])
{char ch[255];
int a;
cin >>ch;
cout << ch;
return 0;
}

smile

Цитата(DeadMan83 @ 21.2.2006, 15:09 Найти цитируемый пост)
Глюк компилятора Borland

неа глюк рук smile

Автор: DeadMan83 21.2.2006, 16:36
Romikgy
а если я введу строку длиной больше 256 символов?smile
твой код тож глючит
Цитата

неа глюк рук

глюк не в том что выдаеться ошибка, а втом что она в первом случае не возникает. Если посмотретькуда указывает ch, то в первом случае указатель равен чтото типа 0x007а21с0, а во втором случае 0x01. Почему в первом случае инициализация не происходи, в отличии от второго - на совести Borland.
PS. А с "ручками" конечно я согласенsmile, указатель надо инициализировать.
кстати вот рабочий код
Код

int main(int argc, char* argv[])
{

 std::string ch;
 std::cin >> ch;
 std::cout << ch;
 return 0;
}

Автор: _hunter 21.2.2006, 16:47
локальные переменные никто не обязан ( я имею в виду компилятор ) инициализировать.
поэтому таки руки виноваты

Автор: DeadMan83 21.2.2006, 16:55
Цитата(_hunter @ 21.2.2006, 16:47 Найти цитируемый пост)
локальные переменные никто не обязан ( я имею в виду компилятор ) инициализировать.
поэтому таки руки виноват

с тобой нельзя не согласитьсяsmile
вот только хотелось бы однозначности от компилятора, если инициализировать, то уж всегда, или вообще не инициализировать (тоже всегда), чтоб была однозначность. да и варнинг можно было бы сгенерить. программист - тоже человек.

Автор: Romikgy 21.2.2006, 16:58
DeadMan83,
Цитата(DeadMan83 @ 21.2.2006, 15:36 Найти цитируемый пост)
а если я введу строку длиной больше 256 символов?

Я это для примера привел, и думаю , что юзер захарится с клавы 255 символов набивать smile
А число можно и другое поставить и динамически выделять smile
Цитата(DeadMan83 @ 21.2.2006, 15:36 Найти цитируемый пост)
Если посмотретькуда указывает ch, то в первом случае указатель равен чтото типа 0x007а21с0, а во втором случае 0x01.

Смысл куда то смотреть при кривом коде?
_hunter, согласен smile

Автор: _hunter 21.2.2006, 17:06
Цитата(DeadMan83 @ 21.2.2006, 15:55 Найти цитируемый пост)
вот только хотелось бы однозначности от компилятора, если инициализировать, то уж всегда, или вообще не инициализировать (тоже всегда), чтоб была однозначность. да и варнинг можно было бы сгенерить. программист - тоже человек.

так это и есть однозначность -- переменная ВСЕГДА устанавливается в случайное значение smile
насчет варнинга... а смысл? может ты специально так задумал.

Автор: DeadMan83 21.2.2006, 17:24
Цитата(_hunter @ 21.2.2006, 17:06 Найти цитируемый пост)
так это и есть однозначность -- переменная ВСЕГДА устанавливается в случайное значение

в том то и фишка что значение во втором случае (когда выдаеться сообщение) не случайно (0x0000001).

Цитата(_hunter @ 21.2.2006, 17:06 Найти цитируемый пост)
насчет варнинга... а смысл? может ты специально так задумал

smile задумал получитиь значение от неинициализированной переменной? чтото не придумываеться такого случая.
гораздо чаще возникает необходимость сделать чтото типа if(a = proc(b)){...} причем сдесь-то варнинг выдаеться.
Цитата(Romikgy @ 21.2.2006, 16:58 Найти цитируемый пост)
А число можно и другое поставить и динамически выделят

интересно как выделять char динамически не зная какая будет длина строки? да и 255 - это не так уж и много

Автор: Fin 21.2.2006, 17:30
Попробуй переписать функцию ввода с клавиатуры. Выделяеш например под буффер ввода 64 байта, устанавливаеш счетчик введенных символов, как только счетчик дошел до предела, расширяй буфер (realloc). Как правило расширяют размер буфера в два раза.

В VC в дебаг режиме, все переменные сразу иницилизируются кодом 0xCC. Иницилизация прописана автоматически.

Автор: _hunter 21.2.2006, 17:39
Цитата(DeadMan83 @ 21.2.2006, 16:24 Найти цитируемый пост)
в том то и фишка что значение во втором случае (когда выдаеться сообщение) не случайно (0x0000001).

ты значение переменной смотри до _выполнения_ следующей _комманды_.
Цитата(DeadMan83 @ 21.2.2006, 16:24 Найти цитируемый пост)
задумал получитиь значение от неинициализированной переменной? чтото не придумываеться такого случая.

а если ты планируеш позже эту переменную инициализировать ( да еще и по условию ( да еще и не в одном месте ) )? ты этк проверку себе представляеш?

Автор: DeadMan83 21.2.2006, 17:42
Цитата(Fin @ 21.2.2006, 17:30 Найти цитируемый пост)
Попробуй переписать функцию ввода с клавиатуры. Выделяеш например под буффер ввода 64 байта, устанавливаеш счетчик введенных символов, как только счетчик дошел до предела, расширяй буфер (realloc). Как правило расширяют размер буфера в два раза.

а зачем изобретать велосипед? не лучше ли воспользоваться тем что уже написано и оттестировано, STL например;)

Цитата(Fin @ 21.2.2006, 17:30 Найти цитируемый пост)
В VC в дебаг режиме, все переменные сразу иницилизируются кодом 0xCC. Иницилизация прописана автоматически

в VC все хорошо обрабатывает, проверял и там, выдает ошибку что произошло обращение к неинициалезированной переменной, что собственно и ожидалось. А вот в Builder все не так.
Добавлено @ 17:46
Цитата(_hunter @ 21.2.2006, 17:39 Найти цитируемый пост)
а если ты планируеш позже эту переменную инициализировать ( да еще и по условию ( да еще и не в одном месте ) )? ты этк проверку себе представляеш?

имелось виду выдавать варнинг при обращении к переменной (получения ее значения) ДО ее инициализации.
Цитата(_hunter @ 21.2.2006, 17:39 Найти цитируемый пост)
ты значение переменной смотри до _выполнения_ следующей _комманды_.

значение я смотрю когда еще выполнение "cin>>ch" не началось. (брейкпоинты ставить умею)

Автор: _hunter 21.2.2006, 17:56
следующая _команда_ это int a smile
Цитата(DeadMan83 @ 21.2.2006, 16:42 Найти цитируемый пост)
имелось виду выдавать варнинг при обращении к переменной (получения ее значения) ДО ее инициализации.

это варниг ты можеш ( и должен ) сам реализовать...

Автор: chwind 21.2.2006, 18:04
это варнинг есть smile
W8013 Possible use of 'identifier' before definition Compiler warning

Автор: DeadMan83 21.2.2006, 18:06
Цитата(_hunter @ 21.2.2006, 17:56 Найти цитируемый пост)
следующая _команда_ это int a

int a - это не команда (попробуй поставить брейкпоинт, посмотреть в режиме дизасма.
а вот int a= 1; - уже команда.
Цитата(_hunter @ 21.2.2006, 17:56 Найти цитируемый пост)
это варниг ты можеш ( и должен ) сам реализовать...

согласен что вызов cin>>ch сложно анализировать и VC ксатит ту варнинг не выводит. но вот попробуй такой код

Код

int _tmain(int argc, _TCHAR* argv[])
{
    char *ch;
    a = (int)ch;
    std::cin>>ch;
    std::cout<<ch;
    return 0;
}

и варнинг тут как тут
Цитата

d:\progs\vistestbug\vistestbug.cpp(11) : warning C4700: local variable 'ch' used without having been initialized

Автор: Vyacheslav 21.2.2006, 18:07
Стандарт не требует инициализировать указатели с помощью Null или с помощью чего либо еще. Так что виноваты руки, а не компилятор.
Borland здесь ничего не нарушает


Автор: Fin 21.2.2006, 18:08
Цитата(DeadMan83 @ 21.2.2006, 16:42 Найти цитируемый пост)
имелось виду выдавать варнинг при обращении к переменной (получения ее значения) ДО ее инициализации.

Единственное как я вижу этот варнинг, это только на стадии компиляции. Да и то, оно им надо (разработчикам).
Пример:
Код

int i;
int a=i;

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

Автор: chwind 21.2.2006, 18:11
Fin, зайди в настройки проекта и включи соответствующий варнинг (W8013) после чего компилятор билдера (да и VC тоже) легко smile будет отлавливать подобные обращениия с переменными

Автор: DeadMan83 21.2.2006, 18:13
Цитата(Fin @ 21.2.2006, 18:08 Найти цитируемый пост)
Пример:

Код
Код

int i
int a=i;


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

сложно но можно. VC (как оказалось и Builder) отслеживает и варнинг выдает.

Цитата(Fin @ 21.2.2006, 18:08 Найти цитируемый пост)
Единственное как я вижу этот варнинг, это только на стадии компиляции. Да и то, оно им надо (разработчикам)

а зачем тогда вообще варнинги??? по мне так чтоб предупредить программиста, что возможно в коде ошибка.

Автор: Fin 21.2.2006, 18:18
Я привел пример в лоб. Если пустить кучу ветвлений (switch), то или Вы компилятор, или компилятор Вас.

Автор: Vassik 21.2.2006, 21:39
Всем спасибо и со всей критикой согласен, только вот то что в одном случае все зашибись, а в другом ошибка, все таки я думаю на совесте компилятора

Автор: Romikgy 22.2.2006, 09:49
Цитата(DeadMan83 @ 21.2.2006, 16:24 Найти цитируемый пост)
интересно как выделять char динамически не зная какая будет длина строки?

Читай по одному символу и каждый раз увеличивай динамический массив

Цитата(DeadMan83 @ 21.2.2006, 16:42 Найти цитируемый пост)
не лучше ли воспользоваться тем что уже написано и оттестировано, STL например;)

STL не является стандартом С++, если я не прав пусть гуру поправят

Автор: _hunter 22.2.2006, 11:23
стандартом -- нет, стандартной библиотекой -- да

Автор: Romikgy 22.2.2006, 12:18
Цитата(_hunter @ 22.2.2006, 10:23 Найти цитируемый пост)
стандартом -- нет, стандартной библиотекой -- да

smile Отож smile

Автор: Vyacheslav 22.2.2006, 12:59
Требования к STL описаны в стандарте языка в главе 17 и она обзывается там как С++ Standard Library и следовательно входит в стандарт

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)