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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 20.09.2009, 19:42   #1
Sambuko
Новичок
Джуниор
 
Регистрация: 20.09.2009
Сообщений: 4
Вопрос Необходима помощь

Здрасте всем. Делаю тестовое задание и столкнулся с неразрешимой для себя задачей. Прошу помощи тех, кто знает

Задача:
Написать шаблон умного указателя для массива (auto_ptr_array).
Пример использования и тестовые сценарии:
Код:
typedef auto_ptr_array< int > TIntArr; 
// пример 1 
{ 
	// размер НЕ ПЕРЕДАЕТСЯ! 
	TIntArr arr( new int[ 10 ] );
            ...
};
Код:
// пример 2 
TIntArr GetArray() 
{ 
	TIntArr arr( new int[ 2 ] );  
	arr[ 0 ] = 1; 
	arr[ 1 ] = 1; 
	return arr;  
	//т.е. должны быть правильные конструкторы копирования 
}


Пока я смог сделать следующее:
Код:
template <class T> class AutoPtrArray
{
public:
	T *m;

public:
	AutoPtrArray(T *pData) : m(pData) {}
	AutoPtrArray(const AutoPtrArray &ptr) : m(ptr.m) {} // конструктор копирования
	~AutoPtrArray() { delete [] m; }


	const T &operator [] (int index) const
	{
		return (m[index]);
	}// end [] const

	T &operator [] (int index) 
	{ 
		return (m[index]); 
            }// end 
};

На мой взгляд я всё делаю правильно, но возникают следующие проблемы:
1) Определние, что индекс в [] вышел за пределы массива. Размер я не могу узнать никак, т.к. получаю только указатель.
2) Второй пример у меня не работает, хотя вроде я написал нужный констриктор копирования, но он не вызывается.

Пожалуйста, помогите мне, уже совсем ничего не соображаю, целый день сижу с этими заданиям!

Спасибо
Sambuko вне форума Ответить с цитированием
Старый 20.09.2009, 21:51   #2
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Цитата:
Сообщение от Sambuko Посмотреть сообщение
1) Определние, что индекс в [] вышел за пределы массива. Размер я не могу узнать никак, т.к. получаю только указатель.
А это не задача умного указателя. Так что на это можно забить
Цитата:
Сообщение от Sambuko Посмотреть сообщение
2) Второй пример у меня не работает, хотя вроде я написал нужный констриктор копирования, но он не вызывается.
После работы конструктора копирования у тебя одним и тем же массивом будет владеть два умных указателя. В итоге, при вызове их деструкторов произойдёт попытка повторного удаления одного и того же массива.
Ну и там в параметре разве не нужно указывать параметр шаблона?
AutoPtrArray(const AutoPtrArray<T> &ptr)
pu4koff вне форума Ответить с цитированием
Старый 20.09.2009, 23:53   #3
Sambuko
Новичок
Джуниор
 
Регистрация: 20.09.2009
Сообщений: 4
По умолчанию

В общем я всё сделал

Если кому интересно, то конструктор долежен выглядить следующим образом:
Код:
template <typename T> class auto_ptr_array
{
private:
  T *m;
  int size;

  void zero() { for (int index = 0; index < size; ++index) m[index] = 0; }

public:
  auto_ptr_array(T *pData) : m(pData) , size(_msize(pData)/sizeof(T)) { zero();}
...
};


Единственный вопрос для меня: насколько "легально" использовать функцию _msize? Я её нашёл совершенно случайно и судя по _ она далеко не является стандартной...


Насчёт второй проблемы, нужно было нормально выделять память, т.к. не знал размера, всё не работало. Теперь, когда я его знаю, то всё ок:

Код:
auto_ptr_array(const auto_ptr_array &ptr)  {size = ptr.GetSize(); m = new T[size]; zero();}
Sambuko вне форума Ответить с цитированием
Старый 21.09.2009, 10:07   #4
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Цитата:
Сообщение от Sambuko Посмотреть сообщение
Единственный вопрос для меня: насколько "легально" использовать функцию _msize? Я её нашёл совершенно случайно и судя по _ она далеко не является стандартной...
Вообще-то префикс _ показывает скорее принадлежность к C Runtime Library. Функция эта сишная. Вообще не факт, что всеми компиляторами С++ поддерживается, а не является каким-нибудь Microsoft Specific. Обещается работа с malloc, calloc, realloc, т.е. оператором new тут и не пахнет. Сейчас она работает правильно, но что будет, если кто-то перегрузит оператор new? Правильно. Эта функция выкинет исключение. Вылетит исключение, значит произойдёт утечка памяти. Произойдёт утечка, значит не такой уж и умный указатель у нас. Так же вылетит исключение, если передать указатель на стековый массив или на середину массива (в данном случае правда нет смысла в этом, ибо зачем следить за стековым массивом, да и половину массива не удалишь потом).
Цитата:
Сообщение от Sambuko Посмотреть сообщение
Насчёт второй проблемы, нужно было нормально выделять память
Зачем это её выделять?
И вообще мне реализация не нравится.
Код:
int *a = new int[10];
for (int i = 0; i < 10; ++i)
{
  a[i] = i;
}
auto_ptr_array<int> ptr(a);
// а тут уже в a хранятся одни нули
// мне не понятно зачем массив было обнулять в умном указателе
auto_ptr_array<int> ptr2(ptr);
// тут уже ptr следит за одним массивом,
// а ptr2 - следит за другим массивом того же размера
А вообще, у auto_ptr разрушающее копирование, т.е. в auto_ptr_array<int> ptr2(ptr)
по идее нужно "отобрать" массив у ptr и передать его, без каких-либо изменений, объекту ptr2
pu4koff вне форума Ответить с цитированием
Старый 21.09.2009, 10:30   #5
Sambuko
Новичок
Джуниор
 
Регистрация: 20.09.2009
Сообщений: 4
По умолчанию

Спасибо за совет к конструктору копирования - видимо тогда я уже почти ничего не соображал к вечеру

Насчёт _msize - если вы мне сможете подсказать, как получить размер памяти по указателю ещё каким-либо способом, я буду только рад
Sambuko вне форума Ответить с цитированием
Старый 21.09.2009, 13:20   #6
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Цитата:
Сообщение от Sambuko Посмотреть сообщение
Насчёт _msize - если вы мне сможете подсказать, как получить размер памяти по указателю ещё каким-либо способом, я буду только рад
Вероятно, никак нельзя это проделать (по крайней мере стандартных механизмов в языке никаких для этого не предусмотрено). Разве что передавать размер в качестве параметра в конструктор, но это глупо
Но вообще я не вижу смысла в этом. Умный указатель должен быть максимально похож на обычный указатель. Проверка границ массива тут в принципе не нужна. Хотя, как говорится, хозяин - барин
Посмотри эту статью. Там вкратце расписаны особенности разных умных указателей, может будет полезно. В принципе, можно "слизать" unique_ptr для данной задачи. Ну, разве что, оператор [] добавить и функтор удаления жёстко задать, а не передавать параметром
pu4koff вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Необходима помощь mrwhat Фриланс 7 19.05.2009 09:03
Необходима помощь с кроссбраузерностью sdevil HTML и CSS 1 24.10.2007 01:55
Необходима помощь nimf Свободное общение 0 29.08.2007 10:43
необходима помощь специалиста Ирина Свободное общение 0 09.11.2006 15:52