Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.69/16: Рейтинг темы: голосов - 16, средняя оценка - 4.69
 Аватар для Svinina
5 / 5 / 0
Регистрация: 28.11.2010
Сообщений: 81

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

19.11.2011, 18:53. Показов 3633. Ответов 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
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.11.2011, 18:53
Ответы с готовыми решениями:

Копирование строки в область памяти несколько раз
Нужно скопировать строку str1 в str2 несколько раз, чтобы та размером в 50 бит заполнилась полностью: MODEL small STACK 256 ...

Сделать так, чтобы можно было добавить несколько одинаковых блюд, не кликая несколько раз
Ребята, подскажите! На форме2 надо сделать так, чтобы можно было добавить несколько одинаковых блюд, не кликая несколько раз, а чтобы в...

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

42
 Аватар для Svinina
5 / 5 / 0
Регистрация: 28.11.2010
Сообщений: 81
19.11.2011, 19:45  [ТС]
Студворк — интернет-сервис помощи студентам
Собственно, попробовал запустить этот код, компилятор (Qt'шный) не стал ругаться, программа отработала корректно.
Так где собака то зарыта?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
19.11.2011, 19:51
Svinina, нигде, код абсолютно корректный
0
 Аватар для Svinina
5 / 5 / 0
Регистрация: 28.11.2010
Сообщений: 81
19.11.2011, 19:53  [ТС]
Ну Берс в самом начале написал, что такой код чреват ошибками.
Вот и интересуюсь, какими=)
1
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
19.11.2011, 19:54
Цитата Сообщение от Bers Посмотреть сообщение
Нет никакой гарантии, что NULL - это ноль.
Есть гарантия, что NULL - это невалидный спецадрес, обозначающий, что указатель ни куда не указывает. И усматривают здесь изготовители не компиляторов, всё зависит от начального адреса памяти. На IBM совместимых это должен быть ноль, не зависимо от компиляторов и даже от языков, а сигнальные камни любят память с ноля начинать, а если так сделано, то NULL не имеет права быть нолём, опять таки даже в том случае, если кроскомпилятор прошивок таких коммутаторов выпустит мелкософт.
0
Заблокирован
19.11.2011, 19:57
Цитата Сообщение от Svinina Посмотреть сообщение
Ну Берс в самом начале написал, что такой код чреват ошибками.
Вот и интересуюсь, какими=)

Первый раз delete освобождает память. С этого момента, этот кусок памяти становится "свободным". И система в любой миг может отдать его ещё кому нибудь.

Второй раз delete пытается освободить уже чужую память. И если эта память принадлежит уже кому то там - может произойти порча данных (хотя скорее всего система этот косяк пофиксит, и заломает накосячевший процесс)

Добавлено через 55 секунд
taras atavin, да я уже вразумел)

NULL всегда не_валидный адрес, но не всегда является нулём)
2
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
19.11.2011, 19:58
Цитата Сообщение от Jupiter Посмотреть сообщение
в Си NULL это ноль приведенный к void* в C++ NULL это ноль
Не ноль, а невалидный номер байта. На IBM совместимых гарантировано невалидный номер байта - это ноль, но если сдеать c, или c++ кроскомпилятор для сиганального камня, то там может быть и другое значение NULL.
0
Заблокирован
19.11.2011, 20:00
Цитата Сообщение от taras atavin Посмотреть сообщение
Не ноль, а невалидный номер байта.
Именно ноль, и если я правильно понял, именно из-за этого и был принят nullptr
(что бы различать int равный нулю и void* равный нулю)
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
19.11.2011, 20:01
Цитата Сообщение от Bers Посмотреть сообщение
Говорят: пиши тогда уж просто ноль. Так будит безопаснее.
Опаснее. И именно потому, что NULL - это не всегда ноль.
0
19.11.2011, 20:25

Не по теме:

Цитата Сообщение от Bers Посмотреть сообщение
Второй раз delete пытается освободить уже чужую память. И если эта память принадлежит уже кому то там - может произойти порча данных (хотя скорее всего система этот косяк пофиксит, и заломает накосячевший процесс)
таки Bers прав:), признаю свою ошибку в 22 посту

0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
19.11.2011, 20:40
Цитата Сообщение от Bers Посмотреть сообщение
Гарантированно оно, если delete []a; a=0;
Не?
А если дефайн - никаких гарантий нет.
Наоборот. Если NULL!=0, то по
C++
1
2
a=0;
delete [a];
очень даже произойдёт. А если дефайном, то вопрос только в правильности дефайна, ну так не пользуйся не правильным и при любом значении NULL ничего не произойдёт. Кстати, я никогда не полагаюсь на проверку внутри delete, а всегда пишу явно
C++
1
2
3
4
if (p)
{
 delete [] p;
}
0
Заблокирован
19.11.2011, 20:41
Я такую запись не понимаю:
Цитата Сообщение от taras atavin Посмотреть сообщение
delete [a];
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
19.11.2011, 21:04
Цитата Сообщение от 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  [ТС]
в многозадачных осях все программы работают в виртуальных адресных пространствах, а освобожденная память из них изымается, то есть виртуальный адрес после освобождения становится столь же невалидным, как и NULL
А вот тут можно поподробнее?
Правильно ли я понимаю, что один раз выделив память, а затем ее освободив, физически к этой области памяти процесс уже доступа получить никогда не сможет?
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
19.11.2011, 21:17
Цитата Сообщение от Bers Посмотреть сообщение
Именно ноль, и если я правильно понял, именно из-за этого и был принят nullptr
Нет. Имплементейшн дефайн - это как раз и есть не всегда ноль. А nullptr приняли, чтоб избавиться от макроса в неконтролируеммом заголовке. У меня где то был исходник для убунты, начинающийся с
C++
1
#define NULL 0
, дефайн этот я написал собственноручно, так вот, если такое начало будет в исходнике для сигнального камня, то получим полную фигню. Компилятор и так должен соответствовать архитектуре, не только по значению NULL, а дефайн может быть в любом "левом" заголовке и даже прямо в исходнике, автор которого архитектуру мог не только не учитывать, а ещё и делать для другой архитектуры. Константа же, известная самому компилятору, а не препроцессору, не будет зависеть от таких самодельных дефайнов, а только от компилятора.

Добавлено через 4 минуты
Цитата Сообщение от Bers Посмотреть сообщение
delete [a];
Я тоже эту очепятку не понимаю. Должно быть
C++
1
delete [] a;
0
Заблокирован
19.11.2011, 21:18
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
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
19.11.2011, 21:26
Цитата Сообщение от 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
Заблокирован
19.11.2011, 21:29
Цитата Сообщение от taras atavin Посмотреть сообщение
Foo(0); //А здесь?
Константа не_ноль интерпритируется как инт по умолчанию. Естественно первый вариант
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
19.11.2011, 21:47
Цитата Сообщение от 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
Заблокирован
19.11.2011, 21:48
Цитата Сообщение от taras atavin Посмотреть сообщение
А как быть с nullptr?
эта волшебная константа типа nullptr_t
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
19.11.2011, 21:51
Кстати, студия 2008 не знает ни nullptr, ни NULL_PTR, ни null_ptr, ни NULLPTR.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.11.2011, 21:51

Можно ли создать нераспределенную область памяти если диск С занял все место?
Всем привет! есть вопросик: можно ли создать нераспределенную область памяти если диск С занял все место?? (у меня WinXp, файловая...

Можно ли использовать несколько раз setlocale? Если да, то как?
Можно ли использовать несколько раз setlocale? Если да, то как ?Мне это нужно только лишь потому, что я хочу использовать ASCII символы из...

Можно ли восстановить несколько раз отредактированный документ microsoft word?
Цель: восстановить в начальное состояние отредактированный(несколько раз открывался, изменялся и соответсвенно сохранялся) документ ворд......

Можно ли, проделав эту операцию несколько раз, получить число более 10 000?
На доске записано натуральное число n, 1000 < n < 3000. Вася может прибавить к числу произведение его первой и последней цифры и записать...

Как можно уменьшить код если его куски повторяются по несколько раз?
Здравствуйте. Как можно уменьшить код если его куски повторяются по несколько раз? Для функций это повторения не на столько масштабные и...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Учебный мини "цифровой двойник" = (Сервер = Java + Flask_питон )+(3D = Гугловскаая 4T nvideo + google colab) +( WMS = Odoo на Docker)
anaschu 07.07.2026
Увидел в требованиях к вакансии создателя имитационных моделей связку (REst + Api + WMS + Anylogic + питон + 3D Nvideo), и решил посмотреть, что это такое. Из этого всего я работал более менее. . .
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru