Указатели

  • Автор темы Автор темы Herbert
  • Дата начала Дата начала
H

Herbert

Добрый день.
Проблема моя состоит вот в чем:

Хочу на С сделать программу, чтобы смотреть содержимое любого участка оперативной памяти.

Почему-то не работает этот участок кода:

Код:
…
…
for (i=1;i<=100; i++) {p=i; printf("%d ", *p);}
…
…


То есть пытаюсь просто посмотреть что лежит в памяти, присваивая указателю значения от 1 до 100.
Не работает…выкидывает по ходу выполнения.
Причем если попробовать поэкспериментировать с границами i, то можно найти такие интервалы i где все работает нормально. Например при 6606848<=i<=6619132. То есть вот такой код работает нормально:


Код:
#include <stdio.h>
#include <stdlib.h>

main()

{
int a=0;
int *p;
int i;

p=&a;
printf("%d ", p);
getchar();
for (i=6606848;i<=6619132; i++) { p=i; printf("%d ", *p); }
getchar();
}

Но если попытаться выйти за границы 6606848 6619132 в цикле, то ошибка.
Ошибка возникает при выполнении (компилируется все нормально).
Использую Builder 5.0
Код в стиле С89.

Текст сообщения об ошибке такой:
Project file.exe raised exception class EaccessViolation with message 'Access violation at
address 0040119C. Read of address 00650000'. Process stopped. Use Step or Run to continue.

Скажите, корректно ли вообще пытаться писать подобный код? Или лучше обращаться только к адресам в которые “сам что-то положил” или зарезервировал через malloc, а просто так по памяти не лазить? В памяти есть участки, которые нельзя посмотреть?
 
По-моему, таким образом можно просмотреть только адресное пространство своего же процесса и то только инициализированные его области (в которых что-то содержится).
 
Скажите, корректно ли вообще пытаться писать подобный код?
Не в обиду будь сказано, но если возникает такой вопрос - то Вам ещё рано писать такой код. Для этого нужно знать особенности работы системы памяти Windows, а для этого нужен довольно серьёзный уровень подготовки. Впрочем, если поиграть, то можно, но тогда не удивляйтесь AccessViolation'ам :)

В памяти есть участки, которые нельзя посмотреть?
Да, и довольно много. Некоторые можно только читать, некоторые - только писать, некоторые - выполнять, а некоторые - ничего нельзя (приложению).

Или лучше обращаться только к адресам в которые “сам что-то положил” или зарезервировал через malloc, а просто так по памяти не лазить?
Да, лучше обращаться только по адресам переменных, выделенных самостоятельно (в стеке или через malloc - не принципиально). Причина указана выше.
 
Не поленюсь (в который раз) посоветовать Рихтера - там внятно и подробно описано использование памяти. Например, первые 65К зарезервированы как раз для нахождения ошибочных указателей, и любое обращение по такому адресу приводит к AV.
 
Ok. Всем спасибо. Посмотрю, что в Рихтере пишут...
Просто в книгах по С (из тех что я видел) этот вопрос стороной обходится.
 
Это вопрос не по языку программирования, а по организации памяти операционной системы. С точки зрения языка Ваши действия абсолютно корректны. Иначе бы код не скомпилировался
 
Ok. Всем спасибо. Посмотрю, что в Рихтере пишут...
Просто в книгах по С (из тех что я видел) этот вопрос стороной обходится.
Это и неудивительно. С - язык программирования, а данный вопрос относится скорей к ОС.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!