Форум: Форум C++Разное
Новые темы: 00
PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум C++

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Вопрос по опасности указателей
 
 автор: DEM   (16.08.2008 в 16:14)   письмо автору
 
 

Читая книгу Г. Шилдта ПОЛНЫЙ СПРАВОЧНИК ПО С++ несколько раз встречал примерно такие строки:

Неверный указатель может повредить данные, код программы и аже операционную систему


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


Ну и еще вопрос, в чём тут ошибка:


int x, *p;
x = 10;
*p = x;


Я не стал пистаь инклюды, определение функции и т.д. Написал только содержание этой функции. В книге напсиано что это ошибка, но, хоть убейте, не могу понять где :(

  Ответить  
 
 автор: cheops   (16.08.2008 в 16:33)   письмо автору
 
   для: DEM   (16.08.2008 в 16:14)
 

Имеется в виду в оперативной памяти - максимум что вам грозит, это синий экран смерти, и то если драйвера надумаете писать.

>Ну и еще вопрос, в чём тут ошибка:
Лучше завести новую тему и привести сообщение об ошибке, у меня следующая программа совершенно нормально скомпилировалась. Да и противоречий никаких нет в тексте программы.
#include <stdio.h>

int main()
{
  int x, *p;
  x = 10;
  *p = x;

  return 0;
}

  Ответить  
 
 автор: DEM   (16.08.2008 в 16:41)   письмо автору
 
   для: cheops   (16.08.2008 в 16:33)
 

Спасибо.

У меня тоже нормально компилируется всё, но там написано что так неправильно...

  Ответить  
 
 автор: GeorgeIV   (16.08.2008 в 21:50)   письмо автору
 
   для: DEM   (16.08.2008 в 16:41)
 

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

  Ответить  
 
 автор: AndreyCh   (16.08.2008 в 22:13)   письмо автору
 
   для: GeorgeIV   (16.08.2008 в 21:50)
 

Фактически для компилятора

 int x, *p;
  x = 10;
  *(*p) = x;

т.е.


 int x, *p;
  x = 10;
  (int)p = x;


здесь используется разименованная ссылка на p, фактически - переменная...
и адрес становится = 10 ?

а компилятор ругнулся, но остался не услышанным :)
warning C4700: uninitialized local variable 'p' used
а вот во время выполнения попрут усключения и программа рухнет

Имеется в виду в оперативной памяти - максимум что вам грозит, это синий экран смерти -
это для NT-Based систем а если система вроде Win9X, то можно было и подвесить ее таким кодом, а... при настойчивости - обвалить

  Ответить  
 
 автор: GeorgeIV   (16.08.2008 в 22:46)   письмо автору
 
   для: AndreyCh   (16.08.2008 в 22:13)
 

а как так лихо у тебя из
*p= x
получилось *(*p)=x, а потом и вовсе (если отбросить приведение) p=x.
Это новые правила разыменования?

  Ответить  
 
 автор: AndreyCh   (20.08.2008 в 22:10)   письмо автору
 
   для: GeorgeIV   (16.08.2008 в 22:46)
 

Дык эта, наэтапе компиляции формируется таблица переменных и таблица ссылок.
Компилятор просматривает их и находит, что есть переменная Хэ и ссылка Пэ
поэтому запись *p воспринимается как ссылка на ссылку Пэ, т.е. - работает дальше уже не с адресом, а со значением переменной т.е. инт(Пэ), которая не инициализирована.
Компилятору это фсеравно, sizeof(int) = 32 и адрес =32 bit, вдруг программер в Хэ засунет адрес?
Так что прокатывает компиляция, чего не скажешь о всем остальном
правильно будет
p=&x

  Ответить  
 
 автор: GeorgeIV   (20.08.2008 в 22:43)   письмо автору
 
   для: AndreyCh   (20.08.2008 в 22:10)
 

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

  Ответить  
 
 автор: cheops   (17.08.2008 в 12:21)   письмо автору
 
   для: AndreyCh   (16.08.2008 в 22:13)
 

>Имеется в виду в оперативной памяти - максимум что вам грозит, это синий экран смерти -
>это для NT-Based систем а если система вроде Win9X, то можно было и подвесить ее таким
>кодом, а... при настойчивости - обвалить
Можно, однако, я решил не упоминать это так как решил, если уж DEM использует Visual Studio 8, то Win9X явно и близко не пахнет - просто не встанет под эти версии.

  Ответить  
 
 автор: AndreyCh   (20.08.2008 в 22:13)   письмо автору
 
   для: cheops   (17.08.2008 в 12:21)
 

Да я не думал наводить критику :)
Просто расширил ответ
просто когда писалась книга - 2008 студии еще не было, это собст-но для автора темы...

  Ответить  
 
 автор: like-nix   (18.08.2008 в 03:49)   письмо автору
 
   для: DEM   (16.08.2008 в 16:14)
 

Может в книжке опечатка
может в книжке имелось ввиду p = x; опасно

вместо
int main()
{
  int x, *p;
  x = 10;
  *p = x;

  return 0;
}

имхо лучше использовать
int main()
{
  int x, *p;
  x = 10;
p = &x;
  return 0;
}


если проверять утилитой lclint первый вариант
выдается предупреждение

source.c: (in function main)
source.c:7:4: Variable p used before definition
An rvalue is used that may not be initialized to a value on some execution
path. (Use -usedef to inhibit warning)

  Ответить  
 
 автор: GeorgeIV   (18.08.2008 в 08:34)   письмо автору
 
   для: like-nix   (18.08.2008 в 03:49)
 

Тут вопрос еще контекста задачи. Если нужен синоним x тогда можно так, а если нужна независимая копия x, тогда надо инициализировать p
p= new int;
и записать
*p=x;

  Ответить  
 
 автор: AndreyCh   (20.08.2008 в 22:21)   письмо автору
 
   для: like-nix   (18.08.2008 в 03:49)
 

Опс, ни туда пыцкнул :)

  Ответить  
 
 автор: AndreyCh   (20.08.2008 в 22:22)   письмо автору
 
   для: like-nix   (18.08.2008 в 03:49)
 

Да нет - в книге пример как НЕ надо писать в С,С++
это я для Like-nix

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования