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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.69
Svinina
5 / 5 / 0
Регистрация: 28.11.2010
Сообщений: 81
#1

Можно ли несколько раз делитить область памяти? - C++

19.11.2011, 18:53. Просмотров 1751. Ответов 42
Метки нет (Все метки)

Собственно, чреват ли ошибками код:
C++
1
2
3
4
5
6
7
8
int *a;
 
a = new int[2];
a[0] = 1;
a[1] = 2;
 
delete [] a;
delete [] a;
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.11.2011, 18:53
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Можно ли несколько раз делитить область памяти? (C++):

Можно ли в С++ выделить память под объект в заданную мной область памяти? - C++
Есть код static inline void convertFromTextAlternative(quint8* dst, const QVariant& src){ QString *a = new...

Вывести числа, которые встречаются в массиве несколько раз / один раз - C++
дан массив состоящий из 100 целых чисел. а)Вывести все числа,которие встречаются в етом массиве несколько раз б)Вывести все...

Можно ли разместить переменную в нужную ячейку памяти и реально ли хранить данные, разбросанными по памяти? - C++
Добрый день. Не могу найти информацию по двум вопросам : 1) могу ли я разместить переменную в нужную ячейку памяти. Например: int a...

Разделяемая область памяти - C++
Здравствуйте. Нам задали такое задание - написать программку(ки, ибо больше одного запущенного процесса) и запустить, чтобы выполнилось...

Копирование область памяти - C++
Здравствуйте, у меня не получается прочитать/скопировать память в переменную. Я делаю .dll, так вот записать значения в адрес я смог, а...

Динамическая область памяти функции new - C++
Чистый Си У кого есть варианты с пояснениями Написать пользовательскую функцию, решающую указанную ниже задачу. Массив создается в...

42
Bers
Заблокирован
19.11.2011, 20:41 #31
Я такую запись не понимаю:
Цитата Сообщение от taras atavin Посмотреть сообщение
delete [a];
0
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
19.11.2011, 21:04 #32
Цитата Сообщение от Bers Посмотреть сообщение
не сказать, что хорошо знаю стандарт, но помойму, там идёт проверка на ноль, а не на NULL
На значение NULL без обращения упоминания имени данного макроса, так как проверять просто на ноль нельзя: если ноль - валидный адрес, то это может привести к невозможности выделить память.

Добавлено через 13 минут
Цитата Сообщение от Bers Посмотреть сообщение
Первый раз delete освобождает память. С этого момента, этот кусок памяти становится "свободным". И система в любой миг может отдать его ещё кому нибудь.
Второй раз delete пытается освободить уже чужую память. И если эта память принадлежит уже кому то там - может произойти порча данных
. Нет. Ни каких чужих данных там быть не может: в многозадачных осях все программы работают в виртуальных адресных пространствах, а освобожденная память из них изымается, то есть виртуальный адрес после освобождения становится столь же невалидным, как и NULL, кусок же памяти по тому же физическому адресу, который как раз может быть выдан кому то ещё, после такого выделения окажется в другом виртуальном адресном пространстве, так как они все локальны, глобальны только физические адреса, а в однозадачной системе просто больше никого нет, кому могла бы быть выдана память по тому же адресу. Опасно же второй раз удалять не подряд, если та же самая прога и тот же её екземпляр успеет получить кусок памяти, на который попадёт тот же адрес.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
... f1(...)
{
 static ... *p;
 ...
 p=new ...;
 ...
 delete [] *p;  // Эта строчка выполнилась дважды в разные вызовы f1, а между ними p попал в память выданную f2
}
... f2(...)
{
 static ... *p;
 ...
 p=new ...; 
 ...
 delete [] *p;
}
. И всё таки дважды делитить можно в единственном случае: если между делитами было ещё одно выделение памяти с того же начального адреса.

Добавлено через 4 минуты
То есть
C++
1
2
3
4
5
6
7
8
int *p;
p=new int [...];
...
delete [] p;
...
p=new int [...];
...
delete [] p;
можно.
0
Svinina
5 / 5 / 0
Регистрация: 28.11.2010
Сообщений: 81
19.11.2011, 21:08  [ТС] #33
в многозадачных осях все программы работают в виртуальных адресных пространствах, а освобожденная память из них изымается, то есть виртуальный адрес после освобождения становится столь же невалидным, как и NULL
А вот тут можно поподробнее?
Правильно ли я понимаю, что один раз выделив память, а затем ее освободив, физически к этой области памяти процесс уже доступа получить никогда не сможет?
0
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
19.11.2011, 21:17 #34
Цитата Сообщение от Bers Посмотреть сообщение
Именно ноль, и если я правильно понял, именно из-за этого и был принят nullptr
Нет. Имплементейшн дефайн - это как раз и есть не всегда ноль. А nullptr приняли, чтоб избавиться от макроса в неконтролируеммом заголовке. У меня где то был исходник для убунты, начинающийся с
C++
1
#define NULL 0
, дефайн этот я написал собственноручно, так вот, если такое начало будет в исходнике для сигнального камня, то получим полную фигню. Компилятор и так должен соответствовать архитектуре, не только по значению NULL, а дефайн может быть в любом "левом" заголовке и даже прямо в исходнике, автор которого архитектуру мог не только не учитывать, а ещё и делать для другой архитектуры. Константа же, известная самому компилятору, а не препроцессору, не будет зависеть от таких самодельных дефайнов, а только от компилятора.

Добавлено через 4 минуты
Цитата Сообщение от Bers Посмотреть сообщение
delete [a];
Я тоже эту очепятку не понимаю. Должно быть
C++
1
delete [] a;
0
Bers
Заблокирован
19.11.2011, 21:18 #35
taras atavin,
C++
1
2
3
4
5
6
7
void Foo(int a) {...}
void Foo( void* ptr) {...}
 
...
 
Foo(0); //угадай, какая из функций будит запущена?
           //если угадаешь правильно, поймёшь, зачем нужен nullptr_t
0
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
19.11.2011, 21:26 #36
Цитата Сообщение от Svinina Посмотреть сообщение
А вот тут можно поподробнее?
Правильно ли я понимаю, что один раз выделив память, а затем ее освободив, физически к этой области памяти процесс уже доступа получить никогда не сможет?
Почему "никогда"? К этой памяти можно обратиться, если:
1. Освобождённый адрес находится на странице, содержащей другой, валидный локальный адрес. В этом случае освобожденный адрес тоже должен стать невалидным, но система не в состоянии этого гарантировать. Но память на одной странице не может быть выдана разным процессам, так что чужую память ты таким образом не освободишь и к ней не обратишься.
2. Если память была повторно выделена процессу.

Добавлено через 2 минуты
Цитата Сообщение от Bers Посмотреть сообщение
void Foo(int a) {...}
void Foo( void* ptr) {...}
...
Foo(0); //угадай, какая из функций будит запущена?
* * * * * *//если угадаешь правильно, поймёшь, зачем нужен nullptr_t
C++
1
2
3
4
5
#define NULL 0xFFFF
void Foo(int a) {...}
void Foo( void* ptr) {...}
...
Foo(0); //А здесь? Если NULL дефайнить числом, то и здесь проблема та же, дело не в ноле.
Это ещё одна цель введения nullptr.
0
Bers
Заблокирован
19.11.2011, 21:29 #37
Цитата Сообщение от taras atavin Посмотреть сообщение
Foo(0); //А здесь?
Константа не_ноль интерпритируется как инт по умолчанию. Естественно первый вариант
0
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
19.11.2011, 21:47 #38
Цитата Сообщение от Bers Посмотреть сообщение
Естественно первый вариант
Первый и должен, так как аргумент - число. Но и NULL - тоже число, то есть foo(NULL) вызовет первый вариант, а программист имеет ввиду второй. Если аргумент - переменная указательного типа, то вызовется второй вариант, как и должно быть. Целей может быть много, но в данном случае на самом деле всё таки одна - избавиться от макроса. Почему надо от него избавиться - это уже другой вопрос и проблема со многими аспектами. Возможность ошибочного дефайна - один из них. Второй - вызов перегруженной функции с невалидным указателем, если есть версия c интом. Чтоб не писать
C++
1
2
int *p=NULL;
foo(p);
. Кстати, а как будет здесь:
C++
1
2
3
4
5
6
7
#define NULL (void*)0xFFFF
void foo(int x);
void foo(void *p);
void foo(int *p);
...
foo(0);
foo(NULL);
и здесь:
C++
1
2
3
4
5
6
void foo(int x);
void foo(void *p);
void foo(int *p);
...
foo(0);
foo(nullptr);
? Валидные указаетели все имеют типы, так как являются переменными. Указатель-переменная с невалидным значением тоже имеет тип. А как быть с nullptr? Ведь программист может под этой константой подразумевать невалидный указатель на что угодно, причём ещё и не всегда одно и тоже в разных местах программы.
0
Bers
Заблокирован
19.11.2011, 21:48 #39
Цитата Сообщение от taras atavin Посмотреть сообщение
А как быть с nullptr?
эта волшебная константа типа nullptr_t
0
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
19.11.2011, 21:51 #40
Кстати, студия 2008 не знает ни nullptr, ни NULL_PTR, ни null_ptr, ни NULLPTR.
0
Bers
Заблокирован
19.11.2011, 21:54 #41
Цитата Сообщение от taras atavin Посмотреть сообщение
Кстати, студия 2008 не знает ни nullptr, ни NULL_PTR, ни null_ptr, ни NULLPTR.
ну я свою подружил с NULL_PTR
Только помойму... понту от него нет никакого. Лучше попрежнему юзать NULL
0
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
19.11.2011, 21:56 #42
Цитата Сообщение от Bers Посмотреть сообщение
эта волшебная константа типа nullptr_t
Эйси. А какая версия будет вызвана и по какому принципу это определяется? Ведь программист может хотеть вызвать с невалидным указателем любую версию, принимающую указатель и в разных частях программы ещё и менять своё решение.

Добавлено через 2 минуты
Цитата Сообщение от Bers Посмотреть сообщение
ну я свою подружил с NULL_PTR
дефайном? Так и я могу аналогичным образом подружить g++ с NULL. Только при этом теряется смысл перехода с NULL на NULL_PTR, так как цель его введения - как раз избавиться от макроса.
0
Bers
Заблокирован
19.11.2011, 22:00 #43
Цитата Сообщение от taras atavin Посмотреть сообщение
А какая версия будет вызвана и по какому принципу это определяется?
Хз, у меня студия 2008 и до нового стандарта не апгрейдиццо. Та что я не в курсе.
Но подозреваю, что не скомпилируется из-за неоднозначности.

Цитата Сообщение от taras atavin Посмотреть сообщение
дефайном? Так и я могу аналогичным образом подружить g++ с NULL. Только при этом теряется смысл перехода с NULL на NULL_PTR, так как цель его введения - как раз избавиться от макроса.
Ну для меня смысл - осознавать что это не НОЛЬ, а НУЛЕВОЙ АДРЕС
Поэтому, не NULL, а NULL_PTR
0
19.11.2011, 22:00
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.11.2011, 22:00
Привет! Вот еще темы с ответами:

Указатель на конкретную область памяти - C++
Есть такая программа ArtMoney, с её помощью мы ищем адрес в памяти, затем изменяем значение по указателю, чтобы изменить количество игровой...

Bin файл из Modbus. Прочитать из файла область памяти - C++
Доброго времени суток! Подскажите пожалуйста, у меня есть bin-файл из которого нужно достать данные полученные устройством и хранящиеся...

Закачка файла и перевод в область памяти типа PVOID - C++
В общем моя программа скачивает библиотеку, грузит ее в память и из памяти библиотека грузится в процесс посредством manual mapping. Но...

Ссылка, Указатель, Область памяти выделенная оператором new для указателя - C++
Подскажите пожалуйста, как сделать ссылку на область памяти выделенную оператором new для указателя читая книгу Джесса Либерти в...


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

Или воспользуйтесь поиском по форуму:
43
Ответ Создать тему
Опции темы

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