Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / C++ Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2      [все]
 а где находится длина массива ???  [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]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
petrav
Member

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

Я пока писал предыдущий пост думал об это нюансе. Что хранить: число элементов массива или размер в байтах.
А почему «или»? И то, и другое может быть нужно разным ... подсистемам.

Мне кажется тут всё равно что писать. Или в байтах, или количество элементов. Типы в массивах одинаковы, не полиморфны ни как.
5 май 21, 10:01    [22318635]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
petrav
Member

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

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

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


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

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

Вообще это странно, что у вас пишется количество элементов. Если вы сами выделяете память в некоем storage,
то вы по идее и ответственны за удаление объектов. И сами должны где-то сохранять количество элементов.

Впрочем, я давно это изучал.
5 май 21, 10:18    [22318640]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
andron81
Member

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


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

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

Вообще это странно, что у вас пишется количество элементов. Если вы сами выделяете память в некоем storage,
то вы по идее и ответственны за удаление объектов. И сами должны где-то сохранять количество элементов.

Впрочем, я давно это изучал.


я не вру.
#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;
}

в случае myCls* kk = new myCls[4];
вывод будет такой , в первых 4-х байтах количество индексов :
storage[0]=4
storage[1]=0
storage[2]=0
storage[3]=0
storage[4]=1
storage[5]=0
storage[6]=0
storage[7]=0
storage[8]=2
storage[9]=0
storage[10]=0
storage[11]=0
storage[12]=3
storage[13]=0
storage[14]=0
storage[15]=0
storage[16]=4
storage[17]=0
storage[18]=0
storage[19]=0
storage[20]=0
5 май 21, 10:35    [22318643]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
Dima T
Member

Откуда:
Сообщений: 15795
andron81
...
в случае myCls* kk = new myCls[4];
вывод будет такой , в первых 4-х байтах количество индексов :
...

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

Нигде не прописано как конкретно должно храниться количество выделенных элементов, это отдано на усмотрение рантайма, который может эту инфу хранить как вместе с данными, так и отдельно.
Т.е. в общем случае нельзя узнать размер массива выделенного через new[].
5 май 21, 10:42    [22318648]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 1106
Dima T, один компилятор использовал . тот который в VS ))
5 май 21, 10:45    [22318650]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
a guest
Member

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

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

А ссылочку таки можно?..
https://itanium-cxx-abi.github.io/cxx-abi/abi.html#array-cookies
5 май 21, 11:59    [22318689]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6658
petrav
Вообще это странно, что у вас пишется количество элементов. Если вы сами выделяете память в некоем storage,
то вы по идее и ответственны за удаление объектов. И сами должны где-то сохранять количество элементов.

В C++ перегруженные операторы new/delete отвечают только за низкоуровневое выделение памяти (просто блоками байтов), а не за создание/удаление объектов. За создание объектов (конструктор/деструктор) и учет количества отвечает сам компилятор, и он ничего не знает про внутреннюю структуру выделенных блоков памяти и их размер в момент удаления. Поэтому он резервирует дополнительную память если нужно.
5 май 21, 15:16    [22318836]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
Dimitry Sibiryakov
Member

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

Anatoly Moskovsky
Поэтому он резервирует дополнительную память если нужно.

Отсюда вытекает забавная подколка когда переменная получает из new не тот адрес, который
вернул перегруженный оператор new. Надо будет пошерстить свой код на эти грабли...

Posted via ActualForum NNTP Server 1.5

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

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

Anatoly Moskovsky
Поэтому он резервирует дополнительную память если нужно.

Отсюда вытекает забавная подколка когда переменная получает из new не тот адрес, который
вернул перегруженный оператор new. Надо будет пошерстить свой код на эти грабли...

А вам зачем понадобился такой функционал? Просто интересно.
5 май 21, 15:30    [22318850]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
Dimitry Sibiryakov
Member

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

petrav
А вам зачем понадобился такой функционал?

Я перегружаю оператор new, например, когда мне нужна структура переменной длины. Массивов
таких структур, конечно, не бывает, поэтому именно на эти грабли я не наступлю.
Есть ещё случай, когда структуре требуется определённое выравнивание в памяти.

Posted via ActualForum NNTP Server 1.5

5 май 21, 15:39    [22318860]     Ответить | Цитировать Сообщить модератору
 Re: а где находится длина массива ???  [new]
Dima T
Member

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

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

Отсюда вытекает забавная подколка когда переменная получает из new не тот адрес, который
вернул перегруженный оператор new. Надо будет пошерстить свой код на эти грабли...

А вам зачем понадобился такой функционал? Просто интересно.

Например выровнять под кэшлинию.
5 май 21, 17:11    [22318902]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2      [все]
Все форумы / C++ Ответить