Как правильно создавать структуры??

gonzales
Offline
Зарегистрирован: 13.07.2015

Доброе время суток!

Есть структуры

struct TBoard {
  byte Device_Adress;
  byte Type_ID = 0;
  byte SA_ID = 0;
  byte Func_ID = 0;
  struct TValues Values;
  struct TLink Link;
};

struct TDevice {
  byte Device_ID;
  struct TBoard Board[MAX_BOARDS_ON_DEVICE];
  bool Tested;
};

Я хочу иметь возможность динамически создавать объекты типа TDevice

Device= new TDevice;

но при этом иметь возможность обращаться к конкретному созданному объекту.

Я сначала поступил по простому, создал массив

TDevice* Device[MAX_DEVICE_COUNT];

и уже внутри массива создавал объект

Device[DeviceNum] = new TDevice;

Я был уверен, что память для объектов выделяется по мере их создания. Но оказывается в памяти висит весь массив, не смотря на то, что он практически пустой.

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

Заранее спасибо за ответы 

 

 

gonzales
Offline
Зарегистрирован: 13.07.2015

Нашел вот такой хитрозадый пример

struct TSotrudnik           // структура данных о сотруднике
{
TSotrudnik (void);
char Name[128];  // имя
int Stage;          // возраст
};

TSotrudnik::TSotrudnik (void)
{
// собственно, конструктор
strcpy(Name, "");
Stage = 0;
}

// здесь деструктор переопределять не надо, программа сама знает, что с нужно делать.

class TMyFirm
{
private:
int cnt; // кол-во сотрудников
public:
TSotrudnik* Sotrudnik;   // динамический массив сотрудников
int Count (void);  // возвращает кол-во
int Count (const int); // возвращает кол-во сотрудников со стажем, более указанного
void AddSotr (const AnsiString, const int); // добавить сотрудника
void Delete (const int); // Удалить сотрудника
TMyFirm (void);   // конструктор
~TMyFirm (void);  // деструктор
};

TMyFirm::TMyFirm (void)
{
cnt = 0;
Sotrudnik = new TSotrudnik[cnt+1]; // объявление ДИНАМИЧЕСКОГО массива
}

TMyFirm::~TMyFirm (void) // а вот здесь декструктор нужно переписать
{
delete [] Sotrudnik;
cnt = 0;
}

void TMyFirm::AddSotr (const AnsiString Name, const int Stage)
{
TSotrudnik Buf;
strcpy(Buf.Name, Name.c_str());
Buf.Stage = Stage;
Sotrudnik = (TSotrudnik*)ReallocMemory(Sotrudnik, (cnt+1)*sizeof(Buf)); // переопределение размера массива
Sotrudnik[cnt] = Buf;
cnt=cnt+1;
}

void TMyFirm::Delete (const int Index)
{
Sotrudnik[Index] = TSotrudnik();
cnt--;
for(int i=Index; i<cnt; i++)
Sotrudnik[i]=Sotrudnik[i+1];
if (cnt > 0)
Sotrudnik = (TSotrudnik*)ReallocMemory(Sotrudnik, cnt);
}

int TMyFirm::Count (void)
{
return cnt;
}

int TMyFirm::Count (const int Stage)
{
int amount=0;
for (int i=0; i<cnt; i++)
if (Sotrudnik[i].Stage > Stage) amount++;
return amount;
}

Получается при создании нового объекта нужно переопределить размер массива. Будет ли такое работать в ардуино?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

gonzales пишет:

создал массив

TDevice* Device[MAX_DEVICE_COUNT];

и уже внутри массива создавал объект

Device[DeviceNum] = new TDevice;

Я был уверен, что память для объектов выделяется по мере их создания. 

Так и есть. Вы создали массив указателей на объекты. Так вот, массив указателей у Вас в памятие сразу весь. А сами объекты получают память по мере создания.

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

Список - это когда каждых элемент содержит указатель на следующий.

Но при это и работать с ним нужно будет как со списком. Т.е. нельзя сразу взять и перейти к i-ому по индексу, а надо идти от начала списка "к следующему", от того "к следующему" и т.д. по всему списку.

Т.е. не зная задачи тут трудно советовать.

gonzales
Offline
Зарегистрирован: 13.07.2015

А как подсчитать, сколько памяти выделяется на массив указателей?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

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

Размер одного указателя, если не знаете, можно легко узнать

Serial.println(sizeof(int *));
gonzales
Offline
Зарегистрирован: 13.07.2015

понял. спасибо!!!