Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите с динамическим массивом объектов 
:(
    Опции темы
mes
Дата 29.10.2008, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(RaP1D @  29.10.2008,  10:12 Найти цитируемый пост)
mes,  мм, нет enemy.size() указывает сколько элементов в массиве создано... 

интересует под сколько элементов памяти уже выделено ? capacity
вот цитата из приведенной вышее ссылки : (http://www.firststeps.ru/mfc/stl/   smile  )
Цитата

    * size() - сколько данных храниться
    * capacity() - сколько может храниться до изменения размера
    * max_size() - максимальный размер обычно равен наиболее большому доступному блоку памяти 




Это сообщение отредактировал(а) mes - 29.10.2008, 12:54


--------------------
PM MAIL WWW   Вверх
RaP1D
Дата 30.10.2008, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 12.10.2008

Репутация: нет
Всего: нет



Еще вопрос:
Есть вектор, состоящий из 100 объектов. Я добавляю туда еще 500. Затем удаляю 300 элементов.
Но память не освобождается. Так и должно быть? А в list тоже также?
PM MAIL   Вверх
baldina
Дата 30.10.2008, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



в list освобождается
в vector нет, она будет использована при последующих добавлениях. принудительно освободить память можно при помощи resize()
PM MAIL   Вверх
RaP1D
Дата 30.10.2008, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 12.10.2008

Репутация: нет
Всего: нет



Не кидайте в меня тапком, решил создать вручную функцию для увеличения размера массива, так сказать для интереса... И столкнулся с проблемой.

Код

#include "stdafx.h"
#include <iostream>
using namespace std;

class Object
{
public:
    int x;
    int y;
};

int num_obj = 3;

Object *obj = new Object [num_obj];

void AddObject(Object *a)
{
    Object *temp = new Object [num_obj]; //создать временный массив
    for(int i=0; i<num_obj; i++) temp[i] = a[i]; //скопировать во временный массив
    delete [] a; //удалить старый массив

    a = new Object [num_obj+1]; //создать новый массив
    for(int i=0; i<num_obj; i++) obj[i] = temp[i]; //скопировать данные обратно
    delete [] temp; //удалить временный массив

    num_obj++; //увеличить число объектов
}


int main()
{
    int pause;

    //забить массив объектов
    for(int i=0; i<num_obj; i++)
    {
        obj[i].x = i;
        obj[i].y = i;
    }

    AddObject(obj);
    //заполнить новый объект
    obj[3].x = 3;
    obj[3].y = 3;

    for(int i=0; i<num_obj; i++)
    {
        cout << obj[i].x << ":" << obj[i].y << endl;
    }

    cin >> pause;
    return 0;
}


В AddObject передается адрес на объект, затем там с ним шаманят, затем этот объект удаляется (delete [] a;) и должен создаться такой же (a = new Object [num_obj+1];)... Код компилируется, вроде работает, но при завершении программы вылетают ошибки...

Я уверен, что ошибка кроется в:
Код

a = new Object [num_obj+1]; //создать новый массив

т.к., если писать:
Код

obj = new Object [num_obj+1]; 

то все ОК...

Как исправить функцию, чтобы она корректно работала?
PM MAIL   Вверх
mes
Дата 30.10.2008, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Код

void AddObject(Object &*a)  // передаем указатель по ссылке
{
    Object *temp = a; // отдаем адрес старого массива временному указателю   
    а = new Object [num_obj+1]; //создаем новый массив
    for(int i=0; i<num_obj; i++) a[i] = temp[i]; //копируем из старого массива в новый
    delete [] temp; //удалить старый массив
    ++num_obj; //увеличить число объектов
}




--------------------
PM MAIL WWW   Вверх
J0ker
Дата 30.10.2008, 23:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 4
Всего: 14



RaP1D, я те ответственно заявляю - быстрее и, что самое главное, прямее STL ты не сделаешь
ты уже понял, как работают динамические массивы
переходи на STL - разберись с аллокатором и будет те щасте  smile 


--------------------
user posted image
PM MAIL   Вверх
RaP1D
Дата 31.10.2008, 09:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 12.10.2008

Репутация: нет
Всего: нет



mes, не, не работает

Код

void AddObject(Object &*a)  //Error    1    error C2528: 'a' : pointer to reference is illegal
{
    Object *temp = a; //Error    2    error C2440: 'initializing' : cannot convert from 'Object **' to 'Object *' 
    а = new Object [num_obj+1]; //Error    3    error C2065: 'а' : undeclared identifier
    for(int i=0; i<num_obj; i++) a[i] = temp[i]; //Error    4    error C2440: '=' : cannot convert from 'Object' to 'Object *'
    delete [] temp; //удалить старый массив
    ++num_obj; //увеличить число объектов
}


void main()
{
...
...
AddObject(obj); //Error    5    error C2664: 'AddObject' : cannot convert parameter 1 from 'Object *' to 'Object **'

...
...
}


Может я неправильно вызываю функцию?

Это сообщение отредактировал(а) RaP1D - 31.10.2008, 09:17
PM MAIL   Вверх
mes
Дата 31.10.2008, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(RaP1D @  31.10.2008,  09:16 Найти цитируемый пост)
Может я неправильно вызываю функцию?

нет я написал неверно...sorry ...  вот подправил :
Код

void AddObject(Object *& a)
{
    Object *temp = a; 
    a = new Object [num_obj+1];
    for(int i=0; i<num_obj; i++) a[i] = temp[i];
    delete [] temp;
    ++num_obj;
}


Это сообщение отредактировал(а) mes - 31.10.2008, 16:12


--------------------
PM MAIL WWW   Вверх
baldina
Дата 31.10.2008, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



RaP1D, более полезно и удобно создать класс-контейнер, который будет иметь соотв. операции, типа:

Код

#include <iostream>
#include <algorithm>
#include <stdexcept>

struct Object
{
    int x;
    int y;
    Object (int x=0, int y=0) : x(x), y(y) {}
};

class ObjectArray {
  Object *array;
  size_t num;

public:
  ObjectArray () : array(0), num(0) {}

  ~ObjectArray () { delete [] array; }

  size_t Count () const { return num; }

  Object& operator [] (size_t i) 
  { 
     if (0 <= i && i < num)
        return array[i];
     else
        throw std::range_error("Index out of range");
  }

  void Resize (size_t n)
  {
    Object *temp = array; 
    array = new Object [n];
    for(size_t i=0; i<std::min(num,n); i++) 
         array[i] = temp[i];
    delete [] temp;
    num = n;
  }

  void AddTail (Object& o)
  {
     Resize (num+1);
     array[num-1] = o;     
  }
};

int main()
{
    ObjectArray obj;

    // изменяем размер, заполняем вручную
    obj.Resize(3);
    for(int i=0; i<3; ++i)
    {
        obj[i].x = i;
        obj[i].y = i;
    }

    // добавляем
    for(int i=0; i<3; ++i)
    {
        Object o(i,i);
        obj.AddTail (o);
    }

    // уменьшаем до 5
    obj.Resize(5);

    for(size_t i=0; i<obj.Count(); ++i)
      std::cout << '(' << obj[i].x << ',' << obj[i].y << ") ";
    std::cout << std::endl;

    // увеличиваем до 8, последние принимают значения по умолчанию
    obj.Resize(8);

    for(size_t i=0; i<obj.Count(); ++i)
      std::cout << '(' << obj[i].x << ',' << obj[i].y << ") ";
    std::cout << std::endl;
 
    std::cin.get ();
    return 0;
}

PM MAIL   Вверх
mes
Дата 31.10.2008, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(baldina @  31.10.2008,  16:59 Найти цитируемый пост)
более полезно и удобно создать класс-контейнер, который будет иметь соотв. операции, типа:

осталось дополнить функциональностью и получится стл-контейнер, который в отличие от самописного готов , проверен и имеет вдовавок кучу алгоритмов. )

Это сообщение отредактировал(а) mes - 31.10.2008, 18:07


--------------------
PM MAIL WWW   Вверх
baldina
Дата 31.10.2008, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



согласен. но человек тренируется и учится, надо помочь ему.

я тут вот еще чуть набросал. идея такая: функций operator [] и Resize()  в принципе достаточно для реализации удаления/добавления без доступа к устройству класса ObjectArray. Поэтому на его базе можно создать нечто вроде PowerObjectArray, который реализует требуемый функционал, не обращаясь к структурам ObjectArray напрямую.

Код

#include <iostream>
#include <algorithm>
#include <stdexcept>

struct Object
{
    int x;
    int y;
    Object (int x=0, int y=0) : x(x), y(y) {}
};

class ObjectArray {
  Object *array;
  size_t num;

public:
  ObjectArray () : array(0), num(0) {}

  ~ObjectArray () { delete [] array; }

  size_t Count () const { return num; }

  Object& At (size_t i) 
  {
     if (0 <= i && i < num)
        return array[i];
     else
        throw std::range_error("Index out of range");
  }

  Object& operator [] (size_t i) 
  { 
    return At(i);
  }

  void Resize (size_t n)
  {
    Object *temp = array; 
    array = new Object [n];
    for(size_t i=0; i<std::min(num,n); i++) 
         array[i] = temp[i];
    delete [] temp;
    num = n;
  }
};

class PowerObjectArray : public ObjectArray {
 
  public:

  void Move (size_t to, size_t from)
  {
    int distance = from - to;
    if (distance < 0)
    {
      Resize (Count()-distance);
      for (size_t i=Count()-1+distance; i != from-1; --i)
        At(i-distance) = At(i);
    }
    else if (distance > 0)
    {
      for (size_t i=to; i < Count()-distance; ++i)
        At(i) = At(i+distance);
      Resize (Count()-distance);
    }
  }

  void Delete (size_t index)
  {
     Move (index, index+1);
  }

  void Insert (Object& o, size_t index)
  {
     Move (index+1, index);
     At(index) = o;
  }

  void AddFront (Object& o)
  {
     Insert (o, 0);
  }

  void AddTail (Object& o)
  {
     Resize (Count()+1);
     At(Count()-1) = o;
  }
};

int main()
{
    PowerObjectArray obj;

    // изменяем размер, заполняем вручную
    obj.Resize(3);
    for(int i=0; i<3; ++i)
        obj[i] = Object(i+1, i+1);

    // добавляем
    for(int i=0; i<3; ++i)
        obj.AddTail (Object(i+4,i+4));

    // уменьшаем до 5
    obj.Resize(5);

    for(size_t i=0; i<obj.Count(); ++i)
      std::cout << '(' << obj[i].x << ',' << obj[i].y << ") ";
    std::cout << std::endl;

    // увеличиваем до 8, последние принимают значения по умолчанию
    obj.Resize(8);


    obj.Delete (2);
    for(size_t i=0; i<obj.Count(); ++i)
      std::cout << '(' << obj[i].x << ',' << obj[i].y << ") ";
    std::cout << std::endl;

    obj.AddFront (Object(100,100));
    for(size_t i=0; i<obj.Count(); ++i)
      std::cout << '(' << obj[i].x << ',' << obj[i].y << ") ";
    std::cout << std::endl;

    obj.AddTail (Object(200,200));
    for(size_t i=0; i<obj.Count(); ++i)
      std::cout << '(' << obj[i].x << ',' << obj[i].y << ") ";
    std::cout << std::endl;

    obj.Insert (Object(300,300),5);
    for(size_t i=0; i<obj.Count(); ++i)
      std::cout << '(' << obj[i].x << ',' << obj[i].y << ") ";
    std::cout << std::endl;

    obj.Move (obj.Count (),0);
    for(size_t i=0; i<obj.Count(); ++i)
      std::cout << '(' << obj[i].x << ',' << obj[i].y << ") ";
    std::cout << std::endl;

    obj.Move (0,obj.Count ()-1);
    for(size_t i=0; i<obj.Count(); ++i)
      std::cout << '(' << obj[i].x << ',' << obj[i].y << ") ";
    std::cout << std::endl;
 
    std::cin.get ();
    return 0;
}



Если реализация ObjectArray изменится, например он перестанет вести себя прямолинейно и перераспределять память при каждом чихе, PowerObjectArray менять не придется.

RaP1D, посмотри, но имей в виду, что это только для понимания концепций и тренировки. для применения в реальных полезных программах есть стандартные контейнеры vector, list и т.д.
PM MAIL   Вверх
RaP1D
Дата 31.10.2008, 21:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 12.10.2008

Репутация: нет
Всего: нет



baldina, 
mes, 
Большущее спасибо!!! smile 

О-ба-на... При использовании вектора показывает 200FPS при 3000 объектах, а при использовании самописной функции 604FPS при 3000 объектах!!!  smile 

Это сообщение отредактировал(а) RaP1D - 31.10.2008, 21:47
PM MAIL   Вверх
mes
Дата 31.10.2008, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(RaP1D @  31.10.2008,  21:10 Найти цитируемый пост)
О-ба-на... При использовании вектора показывает 200FPS при 3000 объектах, а при использовании самописной функции 604FPS при 3000 объектах!!! 

можешь выложить оба тестовых примера ? 


--------------------
PM MAIL WWW   Вверх
baldina
Дата 31.10.2008, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



ага, и скажи заодно какой компилятор и с какими опциями компиляешь.
кстати, заодно, сколько FPS при отсутствии объектов? ;)

Добавлено через 4 минуты и 2 секунды
RaP1D, разницы не должно быть, если ты прост отображаешь свои 3000. разница во вставке/удалении и, поверь, не в пользу самописных.
так что если простой доступ у тебя к vector в 3 раза медленнее, чем к твоему массиву, то либо неправильно используется vector, либо это накладные debug конфигурации.
PM MAIL   Вверх
J0ker
Дата 31.10.2008, 23:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 4
Всего: 14



Цитата(RaP1D @  31.10.2008,  21:10 Найти цитируемый пост)
О-ба-на... При использовании вектора показывает 200FPS при 3000 объектах, а при использовании самописной функции 604FPS при 3000 объектах!!!  smile 

НЭ ВЭРЮ!!!  smile 
Цитата(J0ker @  28.10.2008,  18:42 Найти цитируемый пост)
любым инструментом надо уметь пользоваться




--------------------
user posted image
PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0620 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.