powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / C++ [игнор отключен] [закрыт для гостей] / Аллокация в конструктора массива
61 сообщений из 61, показаны все 3 страниц
Аллокация в конструктора массива
    #40106319
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте - вопрос такой

Есть класс

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
class Pointer {
    uint64_t array[];

public:
    explicit Pointer(int capacity) {
    }


};




Как мне в конструкторе выделить память в размере capacity для массива array ? (Массив нужен именно на стеке)
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106321
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0,

А зачем??? Чтобы деструктор не писать?

Возьми какой-нибудь стандартный контейнер (vector например) вместо примитивного массива и сможешь задать ему размер в конструкторе класса, а деструктор контейнера отработает автоматически когда элемент твоего класса "лежащий на стеке" умрет.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106323
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owl
indigodye0,

А зачем??? Чтобы деструктор не писать?

Возьми какой-нибудь стандартный контейнер (vector например) вместо примитивного массива и сможешь задать ему размер в конструкторе класса, а деструктор контейнера отработает автоматически когда элемент твоего класса "лежащий на стеке" умрет.



Вопрос позвольяет ли так сделать С++ ?
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106324
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Самое простое - перековать в темплейт. Тогда получится ещё один std::array.
Чуть посложнее - использовать calloc().
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106325
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

Чуть посложнее - использовать calloc().


А как это будет выглядеть ?
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106327
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0
White Owl
indigodye0,

А зачем??? Чтобы деструктор не писать?

Возьми какой-нибудь стандартный контейнер (vector например) вместо примитивного массива и сможешь задать ему размер в конструкторе класса, а деструктор контейнера отработает автоматически когда элемент твоего класса "лежащий на стеке" умрет.



Вопрос позвольяет ли так сделать С++ ?
Как? Так как я написал? Да позволяет.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
class Pointer {
    std::vector<uint64_t> array;

public:
    explicit Pointer(int capacity) {
        array.reserve(capacity);
    }
};

И все.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106329
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owl
indigodye0
пропущено...



Вопрос позвольяет ли так сделать С++ ?
Как? Так как я написал? Да позволяет.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
class Pointer {
    std::vector<uint64_t> array;

public:
    explicit Pointer(int capacity) {
        array.reserve(capacity);
    }
};

И все.


Нет не все

Это ответ на какой то другой вопрос
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106330
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Самый главный вопрос тут

А сколько вообще памяти будет выделено в приведенном выше коде ?
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106332
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0
Самый главный вопрос тут

А сколько вообще памяти будет выделено в приведенном выше коде ?
sizeof(Pointer)+sizeof(uint64_t)*capacity;
sizeof(Pointer) будет лежать на стеке а sizeof(uint64_t)*capacity ляжет там куда конструктор vector ее положит. На малых размерах оно может и на стеке лежать, на больших в кучу пойдет. Зависит от имплементации.

Что тебе конкретно нужно то?
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106333
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owl
indigodye0
Самый главный вопрос тут

А сколько вообще памяти будет выделено в приведенном выше коде ?
sizeof(Pointer)+sizeof(uint64_t)*capacity;
sizeof(Pointer) будет лежать на стеке а sizeof(uint64_t)*capacity ляжет там куда конструктор vector ее положит. На малых размерах оно может и на стеке лежать, на больших в кучу пойдет. Зависит от имплементации.

Что тебе конкретно нужно то?



Не в векторе а в моем исходном коде

uint64_t array[];


Сколько тут выделится памяти ?

Нисколько ? А в чем тогда смысл такого объявления ?
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106335
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
---На малых размерах оно может и на стеке лежать


А как мне без внешних коллекций все на стек положить

Вектор то это как то делает
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106336
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0

Не в векторе а в моем исходном коде

uint64_t array[];


Сколько тут выделится памяти ?

Нисколько ? А в чем тогда смысл такого объявления ?
Выделиться скорее всего sizeof(void*)

Смысл? Ну скорее всего это может быть "напоминанием" для человека что данный член класса это массив. И его надо объявлять/уничтожать через new[]/delete[]. Практически ничем не отличается в работе от указателя.

Еще это может быть попыткой повторить прием с простого С. Там так можно делать массивы переменной длины внутри структур.
Код: plaintext
1.
2.
3.
4.
5.
   struct A (
     int x;
     int arr[];
   }
   struct A *a = malloc(sizeof(struct A)+ sizeof(int)*capacity);

Но для С++ класса это работать не будет.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106339
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owl

uint64_t array[];


White Owl

И его надо объявлять/уничтожать через new[]/delete[]]


uint64_t array[]; как поле внутри С++ класса можно объявлять/уничтожать через new[]/delete[]] ?
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106342
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0
---На малых размерах оно может и на стеке лежать


А как мне без внешних коллекций все на стек положить

Вектор то это как то делает
Что такое внешняя коллекция?

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


Выделять на стеке или в куче можно примерно так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
#define MAX_ON_STACK 16
template<T>
class vector {
  int size;
  int capacity;
  bool useArrS;
  union {
      T arrS[MAX_ON_STACK];
      T *arr;
  }
  vector(int capacity) {
    useArrS = true;
    resize(capacity);    
  }

  void resize(int newCapacity) {
     if(capacity <= MAX_ON_STACK && useArrS) return;
     useArrS = false;
     T arrNew = new[newCapacity];
     copy(arr, arrNew, min(newCapacity, size));
     delete []arr;
     arr = newArr;
  }
  const T& at(int pos) {
    if (useArrS)
       return arrS[pos]; 
    else 
      return arr[pos];
  }
};
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106345
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0А как это будет выглядеть ?

Вызов функции в языке программирования всегда выглядит как вызов функции. Что
тебе неясно после прочтения описания этой функции?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106349
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
    uint64_t array[];

    array = calloc()



Работать не будет вроде ?
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106350
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Используй std::array, он на стэке создается.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106351
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T
Используй std::array, он на стэке создается.


Он щаблонный
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106353
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В конструкторе выделить память на стеке? Теоретически конечно можно, но зачем? Все, что выделено на стеке, будет освобождено в момент завершения функции - в данном случае в момент завершения конструктора...
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106354
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Barlone
В конструкторе выделить память на стеке? Теоретически конечно можно, но зачем? Все, что выделено на стеке, будет освобождено в момент завершения функции - в данном случае в момент завершения конструктора...


Нет

uint64_t array[];

Будет жить и после завершения конструктора
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106355
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В данном случае всё, что тебе нужно, это
Код: sql
1.
uint64_t array[n];


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106356
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

В данном случае всё, что тебе нужно, это
Код: sql
1.
uint64_t array[n];




И как в качестве n передать capacity из параметра конструктора ?
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106357
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0И как в качестве n передать capacity из параметра конструктора ?

Выкинуть конструктор. Вместе с классом. Просто написать эту строчку там, где
тебе нужен массив в стеке.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106358
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

indigodye0И как в качестве n передать capacity из параметра конструктора ?

Выкинуть конструктор. Вместе с классом. Просто написать эту строчку там, где
тебе нужен массив в стеке.



Ну короче в конструкоре никак.

ясно
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106359
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0Ну короче в конструкоре никак.

Да, для неспособных прочесть документацию - никак. Увы.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106362
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

indigodye0Ну короче в конструкоре никак.

Да, для неспособных прочесть документацию - никак. Увы.


Ну ты же способен прочесть документацию и для тебе тоже похоже никак
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106363
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня нет задачи где такое необходимо.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106364
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

У меня нет задачи где такое необходимо.


Да Брось ты

Ты просто не знаешь ответа на мой вопрос
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106365
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0

Нет

uint64_t array[];

Будет жить и после завершения конструктора
В стандарте так нельзя. Даже если ваш компилятор такое позволяет в качестве расширения, вы должны каким-то образом сначала выделить память, а потом вызвать конструктор для инициализации с помощью placement new
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106368
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Barlone
indigodye0

Нет

uint64_t array[];

Будет жить и после завершения конструктора
В стандарте так нельзя. Даже если ваш компилятор такое позволяет в качестве расширения, вы должны каким-то образом сначала выделить память, а потом вызвать конструктор для инициализации с помощью placement new


http://cpp.sh/8by5js
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106375
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
indigodye0
Вопрос позвольяет ли так сделать С++ ?

Можно.
Но пользоваться это памятью ты сможешь лишь в самом конструкторе...
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106378
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0Ты просто не знаешь ответа на мой вопрос

Ну...

Использовать шаблоны ты не хочешь.
Использовать calloc ты не хочешь.
Использовать простой массив массив ты не хочешь.

Извини, но на твой вопрос ответов больше нет.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106380
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

Использовать calloc ты не хочешь.


Ты так и не раскрыл как ты это себе представляешь
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106381
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
https://en.cppreference.com/w/c/memory/calloc

Calloc выделяет память в куче и вовращает указатель

У нас же вообще то на стеке все
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106386
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0Ты так и не раскрыл как ты это себе представляешь

А, да. Во-первых, я перепутал calloc и alloca. Во-вторых, не учёл, что оно
освободится при завершении текущей процедуры, то есть конструктора.

Значит у тебя остаются всего две возможности: шаблоны и простой массив
переменной длины.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106387
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

Значит у тебя остаются всего две возможности: шаблоны и простой массив
переменной длины.


Все пропало
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106389
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
indigodye0
Dimitry Sibiryakov

Значит у тебя остаются всего две возможности: шаблоны и простой массив
переменной длины.


Все пропало

Ты, наверное, знаешь какой-то хитрый трюк, но проверяешь, не знает ли его кто-то ещё?
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106390
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ъъъъъ
indigodye0
пропущено...


Все пропало

Ты, наверное, знаешь какой-то хитрый трюк, но проверяешь, не знает ли его кто-то ещё?


Нет, просто я был тут недавно на интервью и меня там будущий тим лид спрашивал - как такое сделать

Я сказал что так нельзя

Он уверенно гнал что можно
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106395
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
indigodye0
ъъъъъ
пропущено...

Ты, наверное, знаешь какой-то хитрый трюк, но проверяешь, не знает ли его кто-то ещё?


Нет, просто я был тут недавно на интервью и меня там будущий тим лид спрашивал - как такое сделать

Я сказал что так нельзя

Он уверенно гнал что можно

Можно, но, как уже обсудили, локально, лишь в пределах функции.
...
А ты не выпытал из него, что он имел в виду? А то может, что-то типа "объект на стеке, а в объекте ссылка на блок в куче".
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106396
indigodye0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ъъъъъ
indigodye0
пропущено...


Нет, просто я был тут недавно на интервью и меня там будущий тим лид спрашивал - как такое сделать

Я сказал что так нельзя

Он уверенно гнал что можно

Можно, но, как уже обсудили, локально, лишь в пределах функции.
...
А ты не выпытал из него, что он имел в виду? А то может, что-то типа "объект на стеке, а в объекте ссылка на блок в куче".


Ну не надо думать что я такой идиот и не в курсе про шаблоны alloca и другие "умные" советы

Вопрос звучал равно как я его сюда привел
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106397
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
indigodye0

Как мне в конструкторе выделить память в размере capacity для массива array ? (Массив нужен именно на стеке)

Можно в декларации поля сразу хапнуть много () памяти на стеке, а потом, "динамически", делать её логически доступной, в размере не большем, чем было хапнуто.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106416
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0
Barlone
пропущено...
В стандарте так нельзя. Даже если ваш компилятор такое позволяет в качестве расширения, вы должны каким-то образом сначала выделить память, а потом вызвать конструктор для инициализации с помощью placement new


http://cpp.sh/8by5js
Я же говорю - в стандарте нельзя
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106571
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0, ответ на твой вопрос дюже прост - компилятор должен знать размер типа на этапе компиляции, а массив переменной длины, длина которого задаётся из конструктора в рантайме, этого сделать не позволяет. Тебе остаётся лишь хранить указатель на массив в куче и его размер, управляя выделением памяти из кучи под массив в конструкторе/деструкторе.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106575
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0
https://en.cppreference.com/w/c/memory/calloc

Calloc выделяет память в куче и вовращает указатель

У нас же вообще то на стеке все
Тогда только шаблонный класс, где параметр шаблона - размер массива.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106605
Фотография ну я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0
Здравствуйте - вопрос такой

Есть класс

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
class Pointer {
    uint64_t array[];

public:
    explicit Pointer(int capacity) {
    }


};




Как мне в конструкторе выделить память в размере capacity для массива array ? (Массив нужен именно на стеке)


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
class Pointer {
    uint64_t* m_pArray;

public:
    explicit inline Pointer(size_t capacity) : 
		m_pArray((uint64_t*)alloca(sizeof(m_pArray[0]) * capacity)) {
    }

	uint64_t& at(size_t n){ return m_pArray[n]; };
};

int main()
{
	uint64_t a = 777;
	Pointer p(2);
	uint64_t b = 888;

	p.at(0) = 0;
	p.at(1) = 111;

	return 0;
}
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106634
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну я
Код: plaintext
1.
2.
3.
    explicit inline Pointer(size_t capacity) : 
		m_pArray((uint64_t*)alloca(sizeof(m_pArray[0]) * capacity)) {
    }


Формально это UB даже если к-тор заинлайнится, потому что при выходе из к-тора память выделенная через alloca "освободится", а значит компилятор может туда положить что угодно затирая данные.
То что в каких-то частных случая этого не происходит, делает все это еще сложнее для отладки.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106673
Фотография ну я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
при выходе из к-тора память выделенная через alloca "освободится"

Место на стеке освободится если бы alloca стоял внутри {}.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106682
Фотография ну я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну я
Anatoly Moskovsky
при выходе из к-тора память выделенная через alloca "освободится"

Место на стеке освободится если бы alloca стоял внутри {}.

Да, действительно, неправ я, проверка:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
	uint64_t a = 777;
	
	Pointer p(2);
	p.at(0) = 0;
	p.at(1) = 111;

	Pointer p2(2);
	p2.at(0) = 222;
	p2.at(1) = 333;

	uint64_t b = 888;


Объект p2 затирает данные объекта p.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106749
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну я, разве в стандарте C/C++ есть функции alloca/std::alloca ?
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106803
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
ну я, разве в стандарте C/C++ есть функции alloca/std::alloca ?
В стандарте С alloca - есть.
В стандарте С++ std::alloca - нет.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106804
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну я
Место на стеке освободится если бы alloca стоял внутри {}.

Инициализаторы выполняются в стек фрейме конструктора.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106808
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl
В стандарте С alloca - есть.
В стандарте С++ std::alloca - нет.

В C тоже нет, и в POSIX тоже ))
Но это не отменяет того факта что на многих платформах эта фича существует.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106823
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
White Owl
В стандарте С alloca - есть.
В стандарте С++ std::alloca - нет.

В C тоже нет, и в POSIX тоже ))
Но это не отменяет того факта что на многих платформах эта фича существует.


man allocaCONFORMING TO
This function is not in POSIX.1.

There is evidence that the alloca() function appeared in 32V, PWB, PWB.2, 3BSD, and 4BSD. There is a man page for it in 4.3BSD.
Linux uses the GNU version.


Так что да, в стандарте нет, но в реальных библиотеках все-же есть.
Во всяком случае во всех никсовых библиотеках есть.
А мелкомягкие дают _alloca и _malloca.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106877
Фотография ну я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
ну я, разве в стандарте C/C++ есть функции alloca/std::alloca ?

Нет, в стандарте языка нет такого.
http://www.c-cpp.ru/content/alloca
Другое дело что это в компиляторах есть и трактуется одинаково.
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106952
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl, нет в стандарте ANSI C никакой alloca().
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40106973
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl, "легально" такие вещи реализуются на стеке через placement new.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
#include <cstdlib>
#include <cstdio>
#include <cstdint>

using namespace std;

class Pointer
{

  size_t    cnt;
  uint64_t  array[0];

public:

  size_t count() const
  {
    return this->cnt;
  }

  Pointer ( size_t len )
      : cnt( ( len - ( reinterpret_cast<uint8_t*>( this->array )
              - reinterpret_cast<uint8_t*>( this ) )
          ) / sizeof( this->array[0] ) )
  {}
  
  void* operator new ( size_t size, void* p_ )
  {
    return p_;
  }
};

int main( int argc, char** argv )
{
  uint8_t arr[ sizeof( uint64_t ) * 100 + sizeof( Pointer ) ];
  Pointer & ptr = *new ( &arr ) Pointer( sizeof( arr ) );
  std::printf( "\n%zu\n", ptr.count() );
  std::fflush( stdout );
  return 0;
}

...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40109762
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
indigodye0, может быть собеседующий действительно имел в виду alloca + placement new?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
#include <assert.h>
#include <stdint.h>
#include <stddef.h>
#include <malloc.h>
#include <new>

class stack_buf_t {
private:
  uint64_t _elems[1]; // должен быть последним полем в классе

public:
  static size_t size(int capacity) {
    assert(capacity >= 0);
    return offsetof(stack_buf_t, _elems) + capacity * sizeof(uint64_t);
  }

  // не используйте напрямую, используйте макрос STACK_BUF
  stack_buf_t(int capacity, uint64_t initial_value) {
    assert(capacity >= 0);
    for (int i = 0; i < capacity; i++) {
      _elems[i] = initial_value;
    }
  }

  uint64_t elem(int index) const {
    return _elems[index];
  }
};

// ! внимание: параметр capacity вычисляется 2 раза
#define STACK_BUF(capacity, initial_value) \
  (new(_alloca(stack_buf_t::size(capacity))) stack_buf_t(capacity, initial_value))

void do_something(int count) {
  stack_buf_t* b = STACK_BUF(count, 3);
  for (int i = 0; i < count; i++) {
    assert(b->elem(i) == 3);
  }
}

Но я бы не стал так делать, потому что alloca -- это хождение по тонкому льду :).
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40109961
priti40
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пётр Седов

[/src]Но я бы не стал так делать, потому что alloca -- это хождение по тонкому льду :).


Ага то есть Вы ка бы вывернули класс мехом на изнанку и положили все на стек

А что тут опасного ?
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40110012
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зачем все усложнять? ))
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
#include <memory_resource>
#include <vector>

int main()
{
    // выделяем буфер на стеке для 100 элементов
    char pool[100*sizeof(uint64_t)];
    std::pmr::monotonic_buffer_resource pool_res{pool, sizeof(pool)};

    // используем его в обычном векторе (можно упаковать в класс с нужным апи)
    std::pmr::vector<uint64_t> v1{&pool_res};
    v1.reserve(10);
    v1.push_back(1);
    v1.push_back(2);

    // куча не задействована (пока не вышли за пределы буфера)
}
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40110182
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
priti40
А что тут опасного ?
У меня когда-то давно был примерно такой код:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
void some_func() {
  for (int i = 0; i < примерно_тысяча; i++) {
    another_func();
  }
}

void another_func() {
  указатель = _alloca(примерно_тысяча);
  ...
}

Компилятор Visual C++ 6, в Debug конфигурации всё было нормально. Но вот в Release конфигурации компилятор зачем-то inline-ил вызов функции another_func (хотя она была не такая уж и маленькая), и работало оно так, как будто код такой:
Код: plaintext
1.
2.
3.
4.
5.
6.
void some_func() {
  for (int i = 0; i < примерно_тысяча; i++) {
    указатель = _alloca(примерно_тысяча);
    ...
  }
}

В Win32 для stack-а главного thread-а по умолчанию резервируется диапазон в 1 мб виртуальных адресов. Вот весь этот мегабайт исчерпывался, и программа crash-илась со stack overflow. С тех пор я понял, что alloca -- это грабли, и перестал его использовать. Хотя современный Visual C++ может уже понимает, что не надо inline-ить вызов функции с alloca.

В ATL есть старые макросы для преобразования строк, которые выделяют память через alloca. Потом вместо них сделали более надёжный механизм:
http://msdn.microsoft.com/EN-US/library/87zae4a3(v=VS.120,d=hv.2).aspx ATL and MFC String Conversion Macros
...
There are several important differences between the older string conversion macros and the new string conversion classes:
Old ATL 3.0 Conversion Macros New ATL 7.0 Conversion Classes Allocates memory on the stack.Uses stack memory for small strings. Uses the heap if the stack is not large enough.The string is freed when the function is exited.The string is freed when the variable goes out of scope.Cannot be used in exception handlers.Can be used in exception handlers.Not suitable for use in loops. Memory use grows until the function is exited.Supports use in loops. Loop scope ensures that memory is freed on each iteration.Not good for large strings. Stack space is limited.No problems with large strings. Strings will be allocated on the heap.Usually require USES_CONVERSION to be defined.Never require USES_CONVERSION to be defined.Meaning of OLE depends on definition of OLE2ANSI.OLE is always equivalent to W....
ATL 3.0 String Conversion Macros
...
The destination string is created using _alloca , except when the destination type is BSTR .
Пункт про обработчики исключений сильно настораживает.

Anatoly Moskovsky
Код: plaintext
1.
2.
    // выделяем буфер на стеке для 100 элементов
    char pool[100*sizeof(uint64_t)];

А тут не будет проблем с выравниванием (alignment)? Вроде как для динамических массивов char-ов (new char[size]) гарантируется наилучшее выравнивание, но тут-то массив не динамический. Может лучше так?
Код: plaintext
1.
uint64_t pool[100];
...
Рейтинг: 0 / 0
Аллокация в конструктора массива
    #40110264
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр Седов
А тут не будет проблем с выравниванием (alignment)?

Нет. Гарантируется правильное выравнивание. Как и для любых других аллокаторов.
https://en.cppreference.com/w/cpp/memory/memory_resource/allocate

Хотя конечно если буфер сразу выровнен, то не будет потерян первый невыровненный кусок. Но это всего лишь оптимизация, а не необходимость.
...
Рейтинг: 0 / 0
61 сообщений из 61, показаны все 3 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Аллокация в конструктора массива
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]