Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.01.2012, 23:45   #1
rengen
Пользователь
 
Регистрация: 19.01.2012
Сообщений: 12
По умолчанию Правильное использование кучи

Такая работа с выделением памяти безопасна или я всё таки теряю блоки? Если да, то есть ли способ кроме копирования всех элементов из старого массива в новый с добавлением нового числа? Конечно число это упрощённый пример нужно это все для класса. Получиться тогда жирная функция.

Код:
#include <iostream>
using namespace std;

int *mass; 
char answer;
int accum;
void main()
{
	mass= new int[1];
	accum++;
	do
	{
		cout<<"Create new int?:";
		cin>>answer;
		if(answer=='Y')
		{
			accum++;
			mass= new int[accum];
			cout<<"Was created."<<endl;
			cout<<"accum now:"<<accum;

		}
	}while(answer!='N');

	delete[] mass;
	mass=0;

	cout<<mass;
}
и чем отличается
delete mass;
от
delete[] mass;

Delete[2] mass; освободит память по этому адресу?
rengen вне форума Ответить с цитированием
Старый 24.01.2012, 00:07   #2
sVasilich
Форумчанин
 
Аватар для sVasilich
 
Регистрация: 16.12.2009
Сообщений: 224
По умолчанию

delete[] mass удалит весь массив mass
delete mass удалит начало массива (хотя я здесь могу ошибаться, желательно что бы кто-то более опытный уточнил).
Люди бывают 10 типов: те, кто понимают двоичную систему счисления, и те, кто не понимают...
sVasilich вне форума Ответить с цитированием
Старый 24.01.2012, 00:09   #3
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Delete[2] mass; освободит память по этому адресу?
нет.
delete это если был new object
delete это для new object[n];
в вашем случае происходят потери mass= new int[accum]; тут, так как старую память вы не освобождаете.

Цитата:
delete mass удалит начало массива (хотя я здесь могу ошибаться, желательно что бы кто-то более опытный уточнил).
это ошибка.
но нужно смотреть по стандарту плюсов.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Stilet; 24.01.2012 в 09:00.
Пепел Феникса вне форума Ответить с цитированием
Старый 24.01.2012, 08:12   #4
rengen
Пользователь
 
Регистрация: 19.01.2012
Сообщений: 12
По умолчанию

А как тогда создавать множество динамических объектов? Через список? Но он же медленный! Что, да как делать?


И почему компилятор не устраивает код вроде этого?

Код:
#include <iostream>
using namespace std;

class Bigman
{
public:
	int x;
	int y;
	Bigman()
	{
		cout<<"Bigman was created.";
		x,y=0;
	}
};

int BigmanNumber=0;
Bigman *Bigmans[]; 
char answer;
void main()
{
        Bigmans[0]= new Bigman;
	BigmanNumber++;
	Bigmans[1]= new Bigman;
	BigmanNumber++;
	do
	{
		cout<<"Create new Bigman?(Y\N): ";
		cin>>answer;
		if(answer=='Y')
		{
			Bigmans[BigmanNumber]= new Bigman;
			BigmanNumber++;
		}
	}while(answer!='N');

	for(;BigmanNumber>=0;BigmanNumber--)
	{
		delete Bigmans[BigmanNumber];
	}
}
Объясню словами, не случай если кодом я это не правильно записал.
Создаем массив указателей какого-то класса, и по очереди присваиваем свежий адрес каждой ячейке. Конечно теперь количество объектов ограничено размером массива указателей, но всё же размещаться и удаляться указатели в памяти будут быстрее чем целые объекты.
Или кто-нибудь может предложить альтернативу получше?
rengen вне форума Ответить с цитированием
Старый 24.01.2012, 08:37   #5
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Но он же медленный!
если применять его для произвольного доступа то да.
да и не медленный он.

вообще берите std::vector или std::list.

а в вашем случае нужно не терять старое значение указателя, копировать данные, а потом удалаять старые.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 24.01.2012 в 08:39.
Пепел Феникса вне форума Ответить с цитированием
Старый 24.01.2012, 08:57   #6
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,543
По умолчанию

Цитата:
и чем отличается
delete mass;
от
delete[] mass;
Практически ничем. В С это имело значение. В С++, из-за возможности перегрузки функций, это утратило своё значение. И так и так правильно.
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 24.01.2012, 08:59   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
В С это имело значение.
о да, в С были new и delete.

ничего оно не утратило смысл, как создавали, так же и удаляйте.
иначе работа кода не гарантируется.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 24.01.2012, 09:23   #8
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,543
По умолчанию

Цитата:
о да, в С были new и delete.
Пардон, погорячился. Глянул справочник по С и С++. Спутался. У ранних версий С++ это было существенно. Сейчас это не существенно. Где-то на форуме я уже раскрывал эту тему. Вот не помню где.
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 24.01.2012, 13:22   #9
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Smitt&Wesson Посмотреть сообщение
Пардон, погорячился. Глянул справочник по С и С++. Спутался. У ранних версий С++ это было существенно. Сейчас это не существенно. Где-то на форуме я уже раскрывал эту тему. Вот не помню где.
Существенно. Как выделяли память, так и освобождаем. Иначе - UB.
По стандарту UB.

Все дело в том, что компиляторы обязаны различать метод создания блока (дин. массива), и метод создание отдельного объекта.

Однако сам принцип выделения памяти, и запоминания количества элементов стандартном не регламентирован, и это на усмотрение компиляторов.

Так например, многие компиляторы при выделении памяти под блок, выделяют чуть больше памяти. В начале выделенного блока записывают количество выделенных элементов. А указатель на блок возвращают со смещением (на нулевой элемент).

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

Код:
delete ptr; // здесь удаление массива, или элемента?
Программист должен явно указать это. И если удаляется блок, то компилятор считает, что количество удаляемых элементов нужно взять по смещению слева от адреса (зависит от реализации компилятора).

Поэтому, неизвестно точно, что произойдёт в этом случае:
Код:
int* ptr = new int[100];
delete ptr;
Утечка памяти, крэш, или что-то иное.

http://alenacpp.blogspot.com/2008/01/delete.html
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сортировка КУЧИ!!! bignick Общие вопросы по Java, Java SE, Kotlin 6 11.04.2011 23:08
Правильное использование setw Андрей Чернуха Общие вопросы C/C++ 0 04.01.2011 21:24
Повреждение кучи fosder Помощь студентам 0 08.12.2010 01:36
Правильное использование IBTransaction Sparky БД в Delphi 0 23.05.2010 18:40