Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
zverek
2 / 1 / 0
Регистрация: 18.04.2012
Сообщений: 22
#1

Значение указателей (*ptr.) на пустые ячейки памяти - C++

29.07.2012, 20:42. Просмотров 1079. Ответов 12
Метки нет (Все метки)

Здравствуйте, уважаемые форумчане!
С началом изучения С++ стало возникать множество вопросов.

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

Вот пример.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "stdafx.h"
#include <iostream>
#include <limits.h>
 
using namespace std;
 
int main(int args, char* argv[]){
    
    //выделяем память
    int *ptrI = new int; 
    float *ptrF = new float;
 
    //выводим необходимые значения
    cout << "new int: " << *ptrI << endl << "int min: " << INT_MIN << endl;
    cout << "new float: " << *ptrF << endl << "float min: " << "-2 147 483 648.0" << endl; 
    
    //чтобы консоль сразу не закрывалась
    system("pause");
 
    //отчищаем память
    delete ptrI, ptrF;
 
    return 0;
}
На выходе получаем вот что:
http://saveimg.ru/pictures/29-07-12/...e2829d7e2b.png

Вот некоторые из моих вопросов:
  1. По идее, мы выделяем пустую память т.е. вида "0000000000....". Так ли это?
  2. Если это так, то почему получаем число отрицательное? Ведь в представлении чисел что с плавающей, что с фиксированной точкой наличие 0 в первом бите прямо значит то, что число имеет знак "+". А у нас числа отрицательные.
  3. Я ни черта не понимаю значения формата float! Как выводить его в том виде, в котором мы привыкли видеть его в тетрадках по алгебре?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.07.2012, 20:42
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Значение указателей (*ptr.) на пустые ячейки памяти (C++):

Сдвиг ячейки памяти в массиве с вычитанием указателей - C++
Возник вопрос вот пример: int m = {1, 2, 3, 4, 5} int *p = &amp;m ; // Это получается адрес начала массива. int *q = &amp;m ; //...

Ошибка на стадии выполнения ptr = ptr; - C++
class CObject { friend Parser; // много полей методов, все должны заполняться в парсере } class Parser { CObject * object_...

Не показывать пустые ячейки массива - C++
Вывожу полностью массив, нужно сделать так, что бы не показывало пустые ячейки, а лишь те что со значениями. Количество заполненных ячеек...

Выделить в памяти 1024 ячейки по 8 байт и вывести их адреса(МИНИ менеджер памяти)) - C++
Вот тут появилась такая интересная задача: требуется сделать программу которая управляет 1024 ячейками памяти по 8 байт каждая. т.е. за...

чтение памяти с использованием указателей - C++
Добрый день. У меня такой вопрос - не могу понять правильно ли работает программа. В результате работы выдается адрес для L, cp, ip и lp,...

Классы. Наследование, массив указателей, очистка памяти - C++
Разбираюсь с классами в си++. Имеется следующий код: header.h ...... class Circle :public Figure { public: void show(); }; ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Schizorb
509 / 461 / 16
Регистрация: 07.04.2012
Сообщений: 865
Записей в блоге: 1
Завершенные тесты: 1
29.07.2012, 20:47 #2
3.
C++
1
2
3
#include <iomanip>
// ...
std::cout << "new float: " << std::fixed << std::setprecision(3) << *ptrF << std::endl;
Печатает значение с фиксированной точкой и 3 знаками после неё.
1
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
29.07.2012, 20:51 #3
Цитата Сообщение от zverek Посмотреть сообщение
По идее, мы выделяем пустую память т.е. вида "0000000000....". Так ли это?
нет, не так, пока ее кто-нибудь не проинициализирует в ней будет произвольное значение
вы могли например сделать так
int *ptrI = new int(0);

Цитата Сообщение от zverek Посмотреть сообщение
Если это так, то почему получаем число отрицательное? Ведь в представлении чисел что с плавающей, что с фиксированной точкой наличие 0 в первом бите прямо значит то, что число имеет знак "+". А у нас числа отрицательные.
там лежит мусор, вот и все

Цитата Сообщение от zverek Посмотреть сообщение
Я ни черта не понимаю значения формата float! Как выводить его в том виде, в котором мы привыкли видеть его в тетрадках по алгебре?
использовать манипулятор fixed
1
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
29.07.2012, 20:56 #4
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от zverek Посмотреть сообщение
По идее, мы выделяем пустую память т.е. вида "0000000000....". Так ли это?
Это не так. Память в общем случае содержит неопределённые значения, зависящие от реализации компилятора, операционной системы и фазы Луны.
Есть два исключения: глобальные и статические переменные; для них вызывается конструктор по умолчанию, если не было прописано явного определения значения (у примитивных типов вроде int и float конструктор по умолчанию действительно туда записывает представление нуля для этого типа). То есть для следующего случая программа обязана первым напечатать 0, затем пробел, затем она может напечатать любое нравящееся ей число.
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
 
int x;
 
int main()
{
  int y;
  std::cout << x << " "<< y;
  return 0;
}

Про формат уже сказали.
3
zverek
2 / 1 / 0
Регистрация: 18.04.2012
Сообщений: 22
29.07.2012, 21:56  [ТС] #5
С вопросом номер 3 разобрался.

Уверенно можно сказать, что память не имеет вид "0000...". Да, там действительно что-то другое. Но! Будь там какой-нибудь беспорядочный мусор, то резервируя ячейки памяти до тех, что я использовал ранее, значения указателей менялись бы. Но они не меняются. Тоже примечательно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//выделяем память
    bool *ptrB = new bool;
    signed char *ptrCh = new signed char;
    unsigned char *ptrUnCh = new unsigned char;
    
    //выводим необходимые значения
    cout << "new bool: " << *ptrB << "  0/255" << endl 
        << "new signed char: " << int(*ptrCh) << ",  symbol: " << *ptrCh << endl
        << "new unsigned char: " << int(*ptrUnCh) << ",  symbol: " << *ptrCh << endl;
    
    //чтобы консоль сразу не закрывалась
    system("pause");
 
    //отчищаем память
    delete ptrB, ptrCh, ptrUnCh;
Имеем: http://saveimg.ru/pictures/29-07-12/...ce323963f1.png

У нас три указателя имеют одно и тоже значение (грубо говоря). Не думаю, что причина тому мусор в памяти. Склоняюсь думать что,
Память в общем случае содержит неопределённые значения, зависящие от реализации компилятора, операционной системы и фазы Луны.
И подтверждается это тем, что компилятор постоянно выкидывает одни те же значения указателей.

С первым и соответственно вытекающим вторым вопросами разобрался.

Вопросов больше нет! Благодарю.
0
xADMIRALx
67 / 61 / 1
Регистрация: 09.06.2012
Сообщений: 291
29.07.2012, 21:59 #6
zverek
Это не бейсик что бы переменные устанавливались автоматом в 0 )))
C++
1
2
3
4
*int ptr1 = NULL;
float ptr2 = NULL;
 
printf("%p\t%p\n",ptr1,ptr2);
1
soon
2540 / 1305 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
29.07.2012, 22:04 #7
zverek, это не подтверждение.
Уверенно можно сказать, что память не имеет вид "0000..."
Нет. Уверенно можно сказать, что там будет мусор. Неважно, что будет он из себя представлять, в общем смысле это все равно мусор.
1
zverek
2 / 1 / 0
Регистрация: 18.04.2012
Сообщений: 22
29.07.2012, 22:14  [ТС] #8
Цитата Сообщение от soon Посмотреть сообщение
zverek, это не подтверждение. Нет. Уверенно можно сказать, что там будет мусор. Неважно, что будет он из себя представлять, в общем смысле это все равно мусор.
Я имел в виду, что тот мусор, который там висит, на значение не повлияет.
0
ValeryS
Модератор
6633 / 5040 / 466
Регистрация: 14.02.2011
Сообщений: 16,850
29.07.2012, 22:14 #9
Цитата Сообщение от zverek Посмотреть сообщение
У нас три указателя имеют одно и тоже значение (грубо говоря).
Если ты работаешь в Debug режиме то так и будет
компилятор защищает себя и память
расскажу про VS ( в других наверно что либо подобное) память при выделении будет 0xCCCCCCCC
или 0xCDCDCDCD(вот тебе и отрицательное число) причем при
int* tmp=new int
выделит не 4 байта а много больше, 20 байт перед 4 байта и 20 после
это для того чтобы если вылез за пределы то программа бы не рухнула
там же записывается служебная информация и если не удалил память то по окончании тебе покажут утечку памяти
но все меняется когда переходишь на релиз, никакой служебной области , никакой инициализации вот здесь то и должны выскочить случайные значения.
хотя ОС может быть при запуске процесса и прописывает всю память каким-нибудь волшебным числом, с этим я не разбирался
1
zverek
2 / 1 / 0
Регистрация: 18.04.2012
Сообщений: 22
29.07.2012, 22:19  [ТС] #10
Цитата Сообщение от ValeryS Посмотреть сообщение
Если ты работаешь в Debug режиме то так и будет
компилятор защищает себя и память
расскажу про VS ( в других наверно что либо подобное) память при выделении будет 0xCCCCCCCC
или 0xCDCDCDCD(вот тебе и отрицательное число) причем при
int* tmp=new int
выделит не 4 байта а много больше, 20 байт перед 4 байта и 20 после
это для того чтобы если вылез за пределы то программа бы не рухнула
там же записывается служебная информация и если не удалил память то по окончании тебе покажут утечку памяти
но все меняется когда переходишь на релиз, никакой служебной области , никакой инициализации вот здесь то и должны выскочить случайные значения.
хотя ОС может быть при запуске процесса и прописывает всю память каким-нибудь волшебным числом, с этим я не разбирался
А вот это уже очень интересно!
0
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
29.07.2012, 22:20 #11
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
http://stackoverflow.com/questions/3...alloc-free-new

просвящайтесь что такое 0xBAADF00D (bad food) и подобное
1
alkagolik
Заблокирован
30.07.2012, 00:28 #12
в общем случае память rw составляет цепочку групп транзисторов. В одном положении транзистора имеем значение логического нуля, в другом - логической единицы. Когда программа использует ОП, "она в нее записывает" какие либо данные(меняет ключи переходов транзисторов), но по освобождении участка памяти, информация в ней так и остается пока новая программа не получит в распоряжение этот участок памяти и не запишет в него свои данные. Говорят что эта информация - мусор. Это правда но только отчасти, просто этот мусор не структурирован, а так же одни данные мешаются с другими при отсутствии взаимосвязи между ними. Для размышления - восстановление данных на жестких дисках производится по этому принципу + учитываются особенности файловых систем.
0
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
30.07.2012, 00:36 #13
alkagolik, это очень далеко от обсуждаемой темы потому как после всего этого память проходит:
- менеджер памяти ОС, который распределяет страницы памяти между процессами
- проходит через менеджер памяти glibc/CRT/etc
к этому моменту в страницах находится уже далеко не то, что было при их выделении на уровне ядра

хм, хотя если и так, то все-равно ячейка памяти проходит длительный путь)
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.07.2012, 00:36
Привет! Вот еще темы с ответами:

Проверка выделения памяти указателей через оператор new - C++
И так есть некая структура, экземпляр которой определён как: var ***v; Изначально заполняю экземпляр: v = new var**; // создание...

Динамическое выделение памяти для массива указателей на char - C++
Доброго времени суток! пытаюсь выделить память для массива указателей на char следующий код #include &lt;iostream&gt; #include &lt;string.h&gt;...

Динамическое выделение памяти и обработка массива с применением указателей - C++
Уплотнить заданную матрицу, удалив из неё строки и столбцы, заполненные нулями. Найти номер первой из строк, содержащих хотя бы один...

Передача массива указателей в функцию для выделения памяти - C++
Есть функция, в которую передаются массивы указателей, для выделения памяти. void str_malloc(char** &amp;strBol,char** &amp;strUvr,char**...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
30.07.2012, 00:36
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru