Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/18: Рейтинг темы: голосов - 18, средняя оценка - 4.94
 Аватар для Mikant
1322 / 995 / 127
Регистрация: 08.12.2009
Сообщений: 1,299

scanf ?

02.04.2010, 23:41. Показов 4051. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
господа, подскажите пожалуйста, почему после этого в VC++ вылетает исключение о нарушении доступа (access violation) к каким-то (по ходу одним из первых) адресам памяти???

C++
1
2
3
4
5
#include <stdio.h>
 
void main(){
    scanf("%lf");
}
даже вопрос разбивается на 2: почему вообще вылетает и почему вылетает ИМЕННО ПОСЛЕ завершения отработки main??? (даже если за этой строкой следует огромная программа)

естественно, если все по-честному делать: scanf("%lf", &buf); то никаких проблем нет.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
02.04.2010, 23:41
Ответы с готовыми решениями:

scanf в C
можна прочитать несколько значений использав всего раз scanf например : scanf (&quot;%d %d&quot;,&amp;a,&amp;b); ? - правильно ли это...

Scanf
#include &lt;iostream&gt; #include &lt;string&gt; #include &lt;cstdio&gt; #include &lt;cstdlib&gt; using namespace std; int maska(string a,string...

scanf()
Всем привет! Вот маленький тестовый пример #include &lt;stdio.h&gt; int i; int main() { printf(&quot;Enter value:...

19
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
03.04.2010, 00:02
потому что вы его неправильно используете.
Это вопрос аналогичен такому
почему код
C++
1
2
int a = 0;
++a;
работает, а
C++
1
2
int a;
++a;
бросает эксепшен
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
03.04.2010, 00:31
Mikant,
C
1
2
3
4
5
6
7
#include <stdio.h>
int main(void){
  double val;
  scanf("%lf", &val);
  printf("Value = %f\n", val);
  return 0;
}
0
 Аватар для Mikant
1322 / 995 / 127
Регистрация: 08.12.2009
Сообщений: 1,299
03.04.2010, 00:50  [ТС]
M128K145, не, ну тут, понятное дело, непроинициализированная переменная... а у меня куда считанный дабл записывается? и когда?

easybudda, если дочитаете мой пост до конца - там это естественно есть

на вопрос ответьте хотя бы на второй, пожалуйста. как и куда память выделяется? я про "физику процесса" спрашиваю, а не про правильные конструкции плюсов. как правильно - везде написано...

Добавлено через 3 минуты
M128K145, тем более ++a выбрасывает исключение в рантайме, а моя конструкция - нет... зараза...
0
 Аватар для kazak
3602 / 2743 / 355
Регистрация: 11.03.2009
Сообщений: 6,304
03.04.2010, 05:06
Исключение выбивает потому что происходит попытка записи в секцию кода, которая по умолчанию имеет атрибут только чтение.
0
 Аватар для Mikant
1322 / 995 / 127
Регистрация: 08.12.2009
Сообщений: 1,299
03.04.2010, 12:45  [ТС]
kazak, а почему запись в эту секцию происходит ПОСЛЕ main??
0
 Аватар для kazak
3602 / 2743 / 355
Регистрация: 11.03.2009
Сообщений: 6,304
03.04.2010, 17:53
А почему ты решил, что это происходит после мэйна?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
03.04.2010, 18:53
Цитата Сообщение от Mikant Посмотреть сообщение
почему вообще вылетает
В scanf'е ты указал "%lf". Сие означает, что следующим параметром ожидается указатель на double. Но указатель ты не подал. Поэтому в том месте памяти, где среди параметров ожидался указатель, реально пришёл мусор (неинициализированное значение). Этот мусор далее начал трактоваться как указатель, по которому внутри scanf'а начала выполняться запись введённого значения. С вероятностью, близкой к единице, такой код сломается

Цитата Сообщение от Mikant Посмотреть сообщение
и почему вылетает ИМЕННО ПОСЛЕ завершения отработки main???
Присоединяюсь к вопросу, а почему ты решил, что после main'а? Но если это и вправду так, то тот мусор, который попал в scanf, оказался всё-таки валидным адресом в адресном пространстве процесса (в том смысле, что этот адрес виртуальной памяти отмапирован на физическую память). И по этому адресу, например, мог лежать адрес возврата из main'а или какая-нибудь другая системная информация, которую запортил scnaf
1
 Аватар для Mikant
1322 / 995 / 127
Регистрация: 08.12.2009
Сообщений: 1,299
03.04.2010, 19:28  [ТС]
Цитата Сообщение от Evg Посмотреть сообщение
почему ты решил, что после main'а
ну, собсна, предыстория такова: у меня студентка курсовую пишет на плюсах (далеко не профиль, а я вообще .NETчик). пишет она прямо в университете, а там на древних компах только и установлен BC++3.1 (91 год, насколько я помню). писала она там, писала и проблем не было. курсовая примитивнейшая: считать из файла данные, пробежаться по ним парой фильтров и выгрузить. ну, естессна, в мэйне тупо подряд несколько вызовов простых функций. в универе - ни одной ошибки ни компилятор не выдает, ни в рантайме не вылетает. скоро им сдавать и позвал я ее к себе домой. дома - VS2008. стал портировать (постоянные предупреждения об использовании небезопасных функций и прочее), все сделал: ни одного предупреждения или ошибки не осталось. далее при запуске программа вела себя как положено, но после завершения (все успешно выгрузив) выдавала это исключение (Необработанное исключение в "0xc0590000" в "DSP.exe": 0xC0000005: Access violation.). при этом на стеке ntdll.dll... -> c0590000(); решил я ошибку отловить. нашел в первой функции (считывания как раз). и уже на форум выложил минималистичный вариант отлова этой ошибки.

зы. при этом открывался еще какой-то файл с кодом, где на его "пустой" строке это исключение и выходило... повтрорить не получается

ззы. если всю программу трассировать по шагам - тот же эффект, соответственно
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
03.04.2010, 20:39
Значит такой кривой scanf затёр в памяти что-то в системной части и после завершения main сломался завершающий код
1
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
04.04.2010, 08:33
Цитата Сообщение от Mikant
все сделал: ни одного предупреждения или ошибки не осталось.
сообщение об ошибке на gcc

Code
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
[guest@station ~]$ ed
a
#include <stdio.h>
 
void main(){
        scanf("%lf");
}
.
2t0
1t$-1
,p
 
#include <stdio.h>
 
void main(){
        scanf("%lf");
 
}
$-1c
    return 0;
.
/scan/
        scanf("%lf");
s/ \+/    /
,p
 
#include <stdio.h>
 
void main(){
    scanf("%lf");
    return 0;
}
/voi/
void main(){
s/void/int/
s/()/(void)/
,p
 
#include <stdio.h>
 
int main(void){
    scanf("%lf");
    return 0;
}
w t.c
73
!gcc t.c -o t
!
!gcc -Wall t.c -o t
t.c: In function ‘main’:
t.c:5: предупреждение: недостаточно аргументов для указанного формата
!
!./t
abcd
!
!rm t t.c
!
q
[guest@station ~]$

она и не должна выдавать, так как может и не быть аргументов

Code
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
[guest@station ~]$ ed
a
 
#include <stdio.h>
 
int main(void)
{
 
}
.
$i
    return 0;
.
,p
 
#include <stdio.h>
 
int main(void)
{
 
    return 0;
}
/{/
{
 
 
c
    scanf("abc");
    scanf("%d");
    printf("abc is entered" "\n");
.
,p
 
#include <stdio.h>
 
int main(void)
{
    scanf("abc");
    scanf("%d");
    printf("abc is entered" "\n");
    return 0;
}
/%d/
    scanf("%d");
m+1
,p
 
#include <stdio.h>
 
int main(void)
{
    scanf("abc");
    printf("abc is entered" "\n");
    scanf("%d");
    return 0;
}
w t.c
124
!gcc -Wall t.c -o t
t.c: In function ‘main’:
t.c:8: предупреждение: недостаточно аргументов для указанного формата
!
!./t
abcdefg
abc is entered
!
!rm t.c t
!
q
[guest@station ~]$
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
04.04.2010, 14:02
accept, с gcc сравнивать не совсем корректно, потому как gcc выдаёт warning не совсем честным способом: он банально "узнаёт" функцию. Старые версии gcc делали это тупо по имени, а в современных версиях в инклюдах у функций printf (и всей группы), scanf (и всей группы) есть некий атрибут (не помню точно как он называется). говорящий о том, что прототип функции соотвествует действию printf'а и scanf'а соответсвенно. И поэтому gcc лезет разбирать форматную строку и проверяет типы последующих аргументов. Хотя компилятор не обязан заниматься такой ерундой. Это всего лишь пользовательская фича, но никак не стандарт языка. Прочие компиляторы как правило этим не заморачиваются и предупреждений не выдают.

Ну и для порядку перечитай 9-й пост: автор выложил короткий пример (а не всю программу) не для того, чтобы мы нашли тут ошибки, а для того, чтобы пояснили, почему программа падает, да ещё и после исполнения main. А "ни одного предупреждения или ошибки не осталось" относилось к полной программе
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
05.04.2010, 02:42
Цитата Сообщение от Evg
И поэтому gcc лезет разбирать форматную строку и проверяет типы последующих аргументов. Хотя компилятор не обязан заниматься такой ерундой.
выше написано, что она не должна проверять

Цитата Сообщение от Evg
Это всего лишь пользовательская фича, но никак не стандарт языка.
lcc тоже выдаёт

так что, либо он не включил предупреждения, либо их там нет

Цитата Сообщение от Evg
А "ни одного предупреждения или ошибки не осталось" относилось к полной программе
это было бы так, если бы он стал запускать программу, которая скомпилировавшись, выдала предупреждение
а он написал, что предупреждений не осталось, он её запустил и она завалилась
и, видимо, он стал это расследовать
и только потом нашёл эту строку
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
05.04.2010, 12:00
accept, ещё раз призываю - прочти внимательно пост автора. Там говорилось про древний компилятор 1991 года. Такие предупреждения там не выдаются. То, что их выдаёт gcc и lcc - абсолютно не показательно
0
 Аватар для kazak
3602 / 2743 / 355
Регистрация: 11.03.2009
Сообщений: 6,304
05.04.2010, 14:47
Странная вещь, компилю такой код
C
1
2
scanf("%f");
printf("Hello\n");
шестой билдер отрабатывает без ислючений, VC и Dev выбрасывают исключение только при запуске из среды или из под отладчика, я в недоумении.
0
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
05.04.2010, 15:07
kazak, билдер никогда не был нормальной IDE
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
05.04.2010, 15:28
Цитата Сообщение от kazak Посмотреть сообщение
шестой билдер отрабатывает без ислючений, VC и Dev выбрасывают исключение только при запуске из среды или из под отладчика, я в недоумении.
В посте 8 я описал причину. Любой код с неинициализированными данными имеет недетерминированное поведение. Т.е. в одной среде он может исполниться так, а в другой сяк. Под "средой" я понимаю не "IDE", а комбинацию "ос + компилятор + библиотеки + переменные окружения и т.п."
1
 Аватар для kazak
3602 / 2743 / 355
Регистрация: 11.03.2009
Сообщений: 6,304
06.04.2010, 13:54
Осознал свою ошибку: аргументы функции заносятся в стек с права на лево и поиск следующих аргументов идет вниз по стеку. Я же почему то решил, что все наоборот и при нехватке какого-либа аргумента, функция непременно наткнется на адрес возврата, запись по которому должна вызывать исключение.
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
07.04.2010, 03:42
Цитата Сообщение от Evg
accept, ещё раз призываю - прочти внимательно пост автора. Там говорилось про древний компилятор 1991 года. Такие предупреждения там не выдаются. То, что их выдаёт gcc и lcc - абсолютно не показательно
там было два компилятора и в обоих предупреждения не было
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
07.04.2010, 09:33
Ещё раз говорю. Если в одном компиляторе есть предупреждение, это вовсе не значит, что в другом тоже будет
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.04.2010, 09:33
Помогаю со студенческими работами здесь

Работа со scanf()
Добрый день! Столкнулась с проблемой при работе с функцией scanf(). Особенно не получается, если тип вводимых данных char. Не работают...

Ошибка в SCANF
warning C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use...

scanf, char
Есть нубский вопрос... char * str=new char; //char str; scanf(&quot;%s&quot;,str); char chr; scanf(&quot;%c&quot;,&amp;chr); В этом коде chr хавает...

Scanf в Eclipse
Всем привет) Подскажите пожалуйста как мне в Eclipse ввести какие-то данные в scanf() Заранее спасибо!

Scanf зацикливание
Почему зацикливается при вводе символа? int a; while (scanf_s(&quot;%d&quot;, &amp;a) != EOF) { ... }


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а привычная функция main(). . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru