Аватар для Svinina
5 / 5 / 0
Регистрация: 28.11.2010
Сообщений: 81

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

19.11.2011, 18:53. Показов 3655. Ответов 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
Ответ Создать тему
Опции темы

Новые блоги и статьи
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины". За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html Задача: . . .
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru