Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / C++ Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 а где находится длина массива ???  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 1106
скажите кто знает , вот разбираясь с перегрузкой оператора new[] для классов, у меня появилось недопонимание. при перегрузке new[] параметр в new sz (тип size_t) он равен всегда количество байт занимаемыми данными массива + 4байта. где 4 байта это ячейки содержащие длину массива. скажем делаю вот так :
myClss* hhX3 = new myClss[2];
в этих четырех байта будет записана двойка. и располагаются эти 4 байта до байт содержащие данные массива
таким образом массив получается в памяти размещается как 4 байта + байты данных массива.

но это как-то не сочетается ведь с пониманием адресной арифметики .
скажем я если сделаю int* x = new int[1]; (будем считать int псевдоклассом)
а затем это x переведу в unsigned char* так :
(unsigned char*)x и начну отнимать -1, -2, -3 (что по себе не очень хорошо, конечно) , то я ведь не выйду ни на какие 4 байта
с длиной массива ???

Сообщение было отредактировано: 4 май 21, 21:32
4 май 21, 21:36    [22318508]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 1106
скажем вот тут я перегрузил new[] (и просто new) для своего класса. память отвожу в обычном статичном массиве store.
и черт побери там то я вижу эти длины в store .

//: C13:GlobalOperatorNew.cpp
#include <cstdio>
#include <cstdlib>
#include <iostream>

const int ElementCount = 100;

unsigned char  store[1002550];

bool  busyStore[ElementCount] = { false };
unsigned char  storeArr[2550];
bool  busyStoreArr[10000] = { false };

class myClss {
    int x;
    /*int y;
    int z;*/
    static int Next;
public:
    myClss() : x(555+Next++){ std::cout << "constr" << std::endl; };
    myClss(int x1) : x(x1){}
    ~myClss() {}
    void* operator new (size_t sz) {
        //std::cout << "here" << std::endl;
        int coord_not_busy = 0;
        for (; busyStore[coord_not_busy]; coord_not_busy++);
        busyStore[coord_not_busy] = true;
        return store + coord_not_busy * sizeof(myClss);
    }

    void operator delete (void* o) {
        unsigned long X = (unsigned long)o - (unsigned long)store;
        busyStore[((unsigned long)o - (unsigned long)store) / sizeof(x)] = false;
        //store+ X = 0;
    }

    void* operator new[](const size_t qty)  {
        int coord_not_busy = 0;
        int byteqtystringFree = 0;
        int x = 0;
        while (x < ElementCount) {
            for (; busyStore[coord_not_busy]; coord_not_busy++); //найдем первый незанятый элемент
            for (x = coord_not_busy, byteqtystringFree = 1; !busyStore[x] && byteqtystringFree < qty; x++, byteqtystringFree++);
            if (!busyStore[x] && byteqtystringFree == qty)

                return store + coord_not_busy  * sizeof(myClss);
            else coord_not_busy = x;
        }
        return 0;
    }

    void printValue() { std::cout << x << std::endl; }


};
int myClss::Next = 0;
int main() {
    myClss* hhX1 = new myClss(111);
    myClss* hhX2 = new myClss(222);
   
    myClss* hhX3 = new myClss[2];
    hhX1->printValue();
    hhX2->printValue();
    hhX3[0].printValue();
    hhX3[1].printValue();
}


Сообщение было отредактировано: 4 май 21, 21:37
4 май 21, 21:45    [22318511]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
petrav
Member

Откуда:
Сообщений: 2944
andron81

(unsigned char*)x и начну отнимать -1, -2, -3 (что по себе не очень хорошо, конечно) , то я ведь не выйду ни на какие 4 байта
с длиной массива ???

Если в вашем менеджере динамической памяти размер массива действительно располагается в четырёх байтах перед самим массивом, то выйдете, конечно, на размер массива. Что ж не выйти то, если он там есть быть?
4 май 21, 21:46    [22318512]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
petrav
Member

Откуда:
Сообщений: 2944
andron81
скажем вот тут я перегрузил new[] (и просто new) для своего класса. память отвожу в обычном статичном массиве store.
и черт побери там то я вижу эти длины в store .

А если вы реализуете свой механизм размещения массивов и видите там размер массива, то вы сами туда его и записываете.
4 май 21, 21:51    [22318515]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
ъъъъъ
Member

Откуда:
Сообщений: 2114
andron81
-1, -2, -3

Итого: минус 6.
Если ты три раза делал по минуc 1, то итого: МИНУС ТРИ.

Сообщение было отредактировано: 4 май 21, 21:48
4 май 21, 21:55    [22318517]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
Dima T
Member

Откуда:
Сообщений: 15795
andron81
а где находится длина массива ???

Нигде
4 май 21, 22:08    [22318521]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 53394

andron81
он равен всегда количество байт занимаемыми данными массива + 4байта.

Нет, не всегда.
#include <stdio.h>

void* operator new[](size_t count)
{
   printf("new[](%u)\n", count);
   return (void*)12345;
}

int main()
{
   int* arr = new int[2];
}

Вывод: new[](8)

Posted via ActualForum NNTP Server 1.5

4 май 21, 22:10    [22318524]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 1106
ъъъъъ
andron81
-1, -2, -3

Итого: минус 6.
Если ты три раза делал по минуc 1, то итого: МИНУС ТРИ.


да, ты прав. Но вот 4 раза , по дилетантски накидал :
int* x = new int[1];
x[0] = 5;
unsigned char* xc = (unsigned char*)x;
std::cout << (int)*(xc) << std::endl;
std::cout<<(int)*(xc - 1)<<std::endl;
std::cout << (int)*(xc - 2) << std::endl;
std::cout << (int)*(xc - 3) << std::endl;
std::cout << (int)*(xc - 4) << std::endl;


видишь тут длину ? я не очень

5
253
253
253
253
4 май 21, 22:10    [22318525]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 1106
Dimitry Sibiryakov

andron81
он равен всегда количество байт занимаемыми данными массива + 4байта.

Нет, не всегда.
#include <stdio.h>

void* operator new[](size_t count)
{
   printf("new[](%u)\n", count);
   return (void*)12345;
}

int main()
{
   int* arr = new int[2];
}

Вывод: new[](8)


может это только в случае классов рисуется сначала 4 байта слева отвечающих за размер массива ? инт можно, конечно воспринимать как класс , но все же может это не для элементарных типов.

Сообщение было отредактировано: 4 май 21, 22:11
4 май 21, 22:16    [22318530]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 53394

andron81
может это только в случае классов рисуется сначала 4 байта слева отвечающих за размер
массива ?

В случае классов размер инстанса увеличивается на указатель на VMT если она есть и на
выравнивание мемберов (а также самой структуры).

Posted via ActualForum NNTP Server 1.5

4 май 21, 22:20    [22318532]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
petrav
Member

Откуда:
Сообщений: 2944
andron81
Dimitry Sibiryakov

пропущено...

Нет, не всегда.
#include <stdio.h>

void* operator new[](size_t count)
{
   printf("new[](%u)\n", count);
   return (void*)12345;
}

int main()
{
   int* arr = new int[2];
}

Вывод: new[](8)


может это только в случае классов рисуется сначала 4 байта слева отвечающих за размер массива ? инт можно, конечно воспринимать как класс , но все же может это не для элементарных типов.

Нет разницы между базовыми типами и классами. Тебя Сибиряков просто обманул таким кодом. И дальше запутывает всякими VMT и выравниваниями.
4 май 21, 22:26    [22318536]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
a guest
Member

Откуда:
Сообщений: 335
andron81
может это только в случае классов рисуется сначала 4 байта слева отвечающих за размер массива ?
Зависит от ABI. Для скалярных типов нет смысла хранить число элементов массива. Для классов с достаточно тривиальными деструкторами тоже.
4 май 21, 22:33    [22318540]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
Siemargl
Member

Откуда: 010100
Сообщений: 6493
andron81,

используй не сырые массивы, а array<> или vector<>

там все есть и это надежнее
4 май 21, 22:48    [22318545]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 1106
petrav
andron81
пропущено...


может это только в случае классов рисуется сначала 4 байта слева отвечающих за размер массива ? инт можно, конечно воспринимать как класс , но все же может это не для элементарных типов.

Нет разницы между базовыми типами и классами. Тебя Сибиряков просто обманул таким кодом. И дальше запутывает всякими VMT и выравниваниями.


базовые пытался вычитать единички. на размер выйти не удалось )))) для примера с перегрузкой размер хранится в хранилище store . получается, что возвращатель return у new [] какой-то умный . он возвращает указатель не на начало всей цепочки байт (ведь цепочка начинается с размера), а с первого элемента. или я не знаю как объяснить.
4 май 21, 23:34    [22318554]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
petrav
Member

Откуда:
Сообщений: 2944
andron81
petrav
пропущено...

Нет разницы между базовыми типами и классами. Тебя Сибиряков просто обманул таким кодом. И дальше запутывает всякими VMT и выравниваниями.


базовые пытался вычитать единички. на размер выйти не удалось )))) для примера с перегрузкой размер хранится в хранилище store . получается, что возвращатель return у new [] какой-то умный . он возвращает указатель не на начало всей цепочки байт (ведь цепочка начинается с размера), а с первого элемента. или я не знаю как объяснить.

Ну вот как тебе пояснить…

Представим, что это мы с тобой разрабатываем управление динамической памятью. Допустим мы разработчики компилятора MinGW. Если мы выделяем массив байт размером N*sizeof(MyStruct), то нам нужно сохранить размер памяти, что бы освободить этот блок памяти. Мы можем размер памяти разместить перед результатом оператора new []. А можем разместить в другом месте.

То что тебе не удалось выйти на размер — это ничего не значит.

Оператор new [] тебе всегда возвращает указатель на первый элемент массива. А то что перед этим указателем может быть записан размер массива или не записан — это не известно.
4 май 21, 23:53    [22318559]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
a guest
Member

Откуда:
Сообщений: 335
petrav
andron81
пропущено...


базовые пытался вычитать единички. на размер выйти не удалось )))) для примера с перегрузкой размер хранится в хранилище store . получается, что возвращатель return у new [] какой-то умный . он возвращает указатель не на начало всей цепочки байт (ведь цепочка начинается с размера), а с первого элемента. или я не знаю как объяснить.

Ну вот как тебе пояснить…

Представим, что это мы с тобой разрабатываем управление динамической памятью. Допустим мы разработчики компилятора MinGW. Если мы выделяем массив байт размером N*sizeof(MyStruct), то нам нужно сохранить размер памяти, что бы освободить этот блок памяти. Мы можем размер памяти разместить перед результатом оператора new []. А можем разместить в другом месте.
Вопрос темы про число элементов массива, а не размер выделенного блока.
5 май 21, 00:16    [22318564]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
petrav
Member

Откуда:
Сообщений: 2944
a guest
petrav
пропущено...

Ну вот как тебе пояснить…

Представим, что это мы с тобой разрабатываем управление динамической памятью. Допустим мы разработчики компилятора MinGW. Если мы выделяем массив байт размером N*sizeof(MyStruct), то нам нужно сохранить размер памяти, что бы освободить этот блок памяти. Мы можем размер памяти разместить перед результатом оператора new []. А можем разместить в другом месте.
Вопрос темы про число элементов массива, а не размер выделенного блока.

Я пока писал предыдущий пост думал об это нюансе. Что хранить: число элементов массива или размер в байтах. Я просто выбрал самое простое решение: хранится размер в байтах. Это, конечно, очень сложная тема. Не готов рассуждать, а ТС-у это не нужно.
5 май 21, 00:29    [22318567]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 53394

andron81
цепочка начинается с размера

Где ты подчерпнул такую идею? Так уже лет 20 никто не делает.

Posted via ActualForum NNTP Server 1.5

5 май 21, 00:32    [22318568]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
a guest
Member

Откуда:
Сообщений: 335
petrav
a guest
пропущено...
Вопрос темы про число элементов массива, а не размер выделенного блока.

Я пока писал предыдущий пост думал об это нюансе. Что хранить: число элементов массива или размер в байтах.
А почему «или»? И то, и другое может быть нужно разным ... подсистемам.
5 май 21, 00:44    [22318569]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
a guest
Member

Откуда:
Сообщений: 335
Dimitry Sibiryakov

andron81
цепочка начинается с размера

Где ты подчерпнул такую идею? Так уже лет 20 никто не делает.
ОП имеет в виду не размер, а число элементов массива. Что в MSVC ABI, что в Itanium C++ ABI при необходимости записывают число элементов массива в начало выделяемого блока.
5 май 21, 00:54    [22318571]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 53394

a guest
Что в MSVC ABI, что в Itanium C++ ABI при необходимости записывают число элементов массива
в начало выделяемого блока.

А ссылочку таки можно?..

Posted via ActualForum NNTP Server 1.5

5 май 21, 01:05    [22318575]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 1106
Dimitry Sibiryakov

a guest
Что в MSVC ABI, что в Itanium C++ ABI при необходимости записывают число элементов массива
в начало выделяемого блока.

А ссылочку таки можно?..


не знаю как насчет ссылки, но экспериментально можно увидеть как new[] пишет в начало количество элементов массива.

#include <iostream>
unsigned char storage[50];
class myCls {
     int iii;
     static int Next;
    public:
        myCls() : iii(Next++) {};
        ~myCls() {};
        void* operator new[](size_t sz) {

            return storage ;
        }

};
int myCls::Next = 1;
int main()
{
    myCls *kk = new myCls[4];
    for (size_t i = 0; i < 50; i++)
        std::cout <<"storage["<<i<<"]" << (int)storage[i] << std::endl;
    
}


самое смешное, что убрав деструктор количество в начало не пишет ))) короче чудеса.

Сообщение было отредактировано: 5 май 21, 08:34
5 май 21, 08:40    [22318599]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 1106
petrav

Оператор new [] тебе всегда возвращает указатель на первый элемент массива.


я ж говорю оператор new[] какой-то умный ))))
5 май 21, 08:45    [22318600]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6658
andron81
самое смешное, что убрав деструктор количество в начало не пишет ))) короче чудеса.

Кол-во элементов массива хранится чтобы можно было для каждого элемента вызвать деструктор при уничтожении массива.
Если тип trivially-destructible то его деструктор не нужно вызывать при уничтожении. Поэтому кол-во элементов массива не требуется знать в рантайме - просто вся память массива высвобождается и все.
5 май 21, 09:19    [22318621]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 1106
Anatoly Moskovsky,

да, логично ! спасибо
5 май 21, 09:38    [22318626]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / C++ Ответить