Вопрос по С++

quant

yeah
возникла необходимость создать стек с возможностью доступа по индексу и для экономии места избавиться от ссылок и воспользоваться линейной структурой
vector не подходит - много места жрёт, создаю свой класс storage
Код:
// 1 interface

class storage {
   private:
      unsigned char * data;
      unsigned length;
   public:
      storage ();
      const unsigned& size() const;
      unsigned char& operator[] (const unsigned&);
      unsigned char backnpop();
      void push (const unsigned char&);
};

// 0 interface implementation 1

storage::storage() : data (NULL), length(0) {
};

const unsigned& storage::size() const {
   return length; 
};

unsigned char& storage::operator[] (const unsigned& pos) {
   return *(data + pos);
};

unsigned char storage::backnpop () {
   return *(data + (--length));
};

void storage::push (const unsigned char& value) {
   unsigned char* temp (new unsigned char[length + 1]);
   unsigned char *t (temp), *d (data);
   unsigned it (0);
   if (length) {   
      do {
         *(t++) = *(d++);
      } while (++it != length);
   };
   *t = value;
   delete [] data;
   data = temp;
   ++length;
};

// 0 implementation
но этот класс работает много медленнее vector'а, почему так ?
 

dreamer

Member
возникла необходимость создать стек с возможностью доступа по индексу и для экономии места избавиться от ссылок и воспользоваться линейной структурой
vector не подходит - много места жрёт, создаю свой класс void
Код:
storage::push (const unsigned char& value) {
   unsigned char* temp (new unsigned char[length + 1]);
но этот класс работает много медленнее vector'а, почему так ?
Потому что ты каждый раз выделяешь память а это одна из самых медленных операций.
 

quant

yeah
а как же тогда в векторе добавляется элемент ? насколько я знаю выделить память в определённой области памяти нельзя - так бы я выделил байт (m + length + 1) и занёс туда value
или есть способ ?
я даже pop полный не делаю, думал оно просто лётать будет
 

dreamer

Member
Память нужно выделять как можно реже, для этого нужно выделить ее про запас и только если запас исчерпан то довыделить и использовать не цикл для копирования старой памяти в новую а низкоуровневые быстрые функции (например memcpy) или вообще не удалять старую а использовать список буферов одинакового размера.
В программировании всегда существует конфликт скорость/память.
 

quant

yeah
спасибо, но как оказывается память можно выделить в определённой области
new (mem_start) type;
теперь push & backnpop приняли совсем иной вид
со старым backnpop иногда вылатала runtime error, а с этим всегда...
Код:
unsigned char storage::backnpop (){
   unsigned char temp (*(data + (--length)));
   delete reinterpret_cast<unsigned char*> (data + length);
   return temp;
};

void storage::push (const unsigned char& value) {
   if (length == 0) {
      *(data = new unsigned char) = value;
      length = 1;
      return;
   };
   *(new (data + (length++)) unsigned char) = value;
};
ещё пытался осилить allocator с его allocate, по видимому так же начиная с какой-то области памяти можно выделять памяти и с помощью аллокатора
std::allocator::allocate (size_type size, void* hint);
вот судя по описанию hint и задаёт начальную позицию, если не равен NULL, но при тестировании это не выполняется
а вариант со списками не пойдёт - нужно как минимум памяти
вообще я никогда не жалею память во имя времени, но тут такая задача
 
Останнє редагування:

dreamer

Member
А ты не думаешь что область, которую ты хочешь выделить может быть уже занята? ;)
 

ZloDigit

New Member
Re: примитив С++

имеется такой вот кусочек кода (к примеру)
Код:
char ссс[16]={0xE8,[COLOR="Red"]0,0,0,0[/COLOR],0x58,04,0x12,0x50,0xFF,0x15,0,0,0,0,0xC3};
int i=(int)GetModuleHandle("boo.dll");
вопрос в том как затолкать значение из i в ту часть переменной ссс которая выделена красным. Другими словами у меня есть 16 байт в памяти, и начиная со второго в 4 из них нужно положить значение из переменной любого типа который тоже весит 4 байта (int, HANDLE, DWORD...)[/QUOTE]

_asm
{
lea ebx,ccc;
lea edx,i; //в принципе
mov eax,[edx]; //тут можно 1й строкой
mov dword ptr [ebx+1],eax;
}
 
Останнє редагування:

ZloDigit

New Member
Выделится она только в Data segment ЕТОЙ задачи причем в динамической области,возможность перезаписи чужих данных исключена-ОС не даст.dreamer прав память нужно выделять зараннее,скажем какой нибудь массив на глобальном уровне,тогда скорость падать не будет,а так ты теряешь на NEW/DELETE
 

dreamer

Member
Выделится она только в Data segment ЕТОЙ задачи причем в динамической области,возможность перезаписи чужих данных исключена-ОС не даст.
А ты думаешь кроме этой строки кода ЭТА задача больше ничего выделять не будет? Я говорю о перезаписи своих данных :)
 
Зверху