LINUX.ORG.RU

Динамический массив в стеке

 


0

1

Господа, прошу прощения за глупый вопрос, но как сделать массив контролируемой длинны в стеке используя C? Например что бы сохранить весь пользовательский ввод из getchar()? Я понимаю что это не корректный подход, но все-же. Может есть какой-то способ алоцировать дополнительную память для массива в стеке?


Обращайся по отрицательным индексам в каком-нибудь массиве на стеке. Но любой вызов другой функции покорёжит стек.

kvap ()

Это не возможно. После твоего массива в стеке могут оказаться другие переменные и расширять массив будет просто некуда. А если всё учитывать, то потребуется какой-никакой, а менеджер памяти, чтобы понять, где в стеке занято, а где свободно. Но в таком случае почему бы не использовать кучу? Она гораздо лучше подходит для этого, чем стек.

Используй malloc, realloc и free и не выпендривайся.

KivApple ★★★★★ ()
Последнее исправление: KivApple (всего исправлений: 1)

alloca? Только это не будет переносимо.

buddhist ★★★★★ ()
Ответ на: комментарий от KivApple

Это не возможно. После твоего массива в стеке могут оказаться другие переменные и расширять массив будет просто некуда.

Именно расширить VLA нельзя, конечно. Но можно сделать новый на месте или, на худой конец, после старого. Та ещё наркомания :) По-настоящему печально то, что нельзя делать «free» в порядке, обратном созданию. Для какого-нибудь специфически-экзотичного случая это может и не быть существенным ограничением.

const86 ★★★★★ ()
Ответ на: комментарий от const86

Но можно сделать новый на месте или, на худой конец, после старого.

Я что-то не понял. В стеке выделяется столько места, сколько нужно для переменной. При расширении массива его размер, очевидно, растёт. Как его можно разместить НА МЕСТЕ предыдущего? А если размещать после, то старый никуда не денется. Будет перерасход памяти. А что если ты последовательно добавишь миллион элементов? Никакой оперативки не хватит, чтобы сохранить все предыдущие версии массива. А если их не сохранять, то нужен менеджер памяти. А если у нас есть менеджер памяти, то зачем ему использовать стек, а не кучу (которая больше и вообще предназначена специально для этого)?

Мне кажется, что автор треда употребляет какие-то специфические вещества... Я не понимаю смысла сего действа, разве что для архитектур, у которых нет кучи, только стек. Но даже для AVR'ок написан malloc (а для чего-то с ещё меньшими ресурсами, чем AVR, вероятно, не стоит использовать что-то сложнее Assembler).

KivApple ★★★★★ ()
Последнее исправление: KivApple (всего исправлений: 5)

Не забываете ещё что стек растёт вниз, так что после массива _всегда_ есть данные. Так что да, никак.

slovazap ★★★★★ ()

Господа, прошу прощения за глупый вопрос, но как сделать массив контролируемой длинны в стеке используя C? Например что бы сохранить весь пользовательский ввод из getchar()? Я понимаю что это не корректный подход

а зачем спрашиваешь?

Выделяй malloc(3), а если мало, выдели вдвое больше, перенеси данные, а старый буфер верни обратно.

И да, есть ещё realloc(3).

emulek ()

Господа, прошу прощения за глупый вопрос, но как сделать массив контролируемой длинны в стеке используя C?

Илитное решение «Царь-эдишон»:

char * arr = malloc(sizeof(char)*100500*100500*...*100500);

(Тебе точно должно хватить... Не хватит - еще на 100500 умножь)

slackwarrior ★★★★★ ()
Ответ на: комментарий от slackwarrior

Илитное решение «Царь-эдишон»:
char * arr = malloc(sizeof(char)*100500*100500*...*100500);

+ char

anonymous ()
Ответ на: комментарий от const86

Но можно сделать новый на месте

нельзя. там просто обязательно будут какие-то данные, которые он затрёт. впрочем неясно, что означает «новый на месте», если массив — это почти просто указатель.

единственный, и притом плохой вариант: делать большой массив, который будет хранить «слева» нужные данные, а «справа» — tmp. по соглашению, в момент расширения массива, данные в tmp части уже должны быть не нужны.

или, на худой конец, после старого.

дичайший оверхед

проблема автора, впрочем, типична и имеет типичное решение — выделять достаточно большой объём памяти. и с ней уже работать, как захочется (для этого даже placement new придумали). но... такое решение предназначено для решения специфических задач, у автора не та и оно, к тому же, немного не то, чего он хочет.

next_time ★★★★★ ()
Ответ на: комментарий от KivApple

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

но там и getch() тупо не работает)

а для чего-то с ещё меньшими ресурсами, чем AVR, вероятно, не стоит использовать что-то сложнее Assembler

ещё как стоит, говорю как человек профессионально этим занимающийся. напротив, там даже плюсов очень не хватает.

next_time ★★★★★ ()
Ответ на: комментарий от next_time

Для AVR - да. Я говорю для чего-то более простой архитектуры, чем AVR, где возникают такие вот вопросы как у ТС.

KivApple ★★★★★ ()
Ответ на: комментарий от KivApple

Я говорю для чего-то более простой архитектуры, чем AVR

и я говорю про, в целом, более простую. конкретно, про 8051

next_time ★★★★★ ()
Ответ на: комментарий от emulek

Емулек, почему ты такой глупый? Ты до сих пор не осилил матчасть.

malloc(total_mem_size); - правильный подход. Динамический от природы.

carb_blog10 ()
Ответ на: комментарий от slackwarrior

А чем плохо такое(моё) решение, ты же мне объяснить осилишь?

И когда это царь был крестовой обезьяной, которая не осилила ни воид, ни голову, ни матчасть? Да ещё и множитначар.

carb_blog10 ()
Ответ на: комментарий от emulek

sysinfo(), либо парси руками meminfo().

#include <sys/sysinfo.h>

uint64_t __total_ram;
__attribute__((constructor)) void __init_total_ram(void) {
  struct sysinfo inf;
  sysinfo(&inf);
  __total_ram = inf.totalram;
}

Вставляешь это куда угодно - у тебя будет глобальный тоталрам. Сам заполняется при старте программы.

carb_blog10 ()
Ответ на: комментарий от carb_blog10

ну и на кой ляд мне нужна программа, которая захавывает ВСЮ память? Я знаю, что она VITR, но это тоже быдлокодерство.

emulek ()
Ответ на: комментарий от emulek

ну и на кой ляд мне нужна программа,

Датычё.

которая захавывает ВСЮ память?

Всю память? Рили? Ты же мне покажешь где она и чего захватывает?

Я знаю

Нет не знаешь, иначе бы ты такую херню не нёс.

что она VITR

Ещё одно подтверждение, что не знаешь. С какой жопы __total_ram стала всей виртуальной?

но это тоже быдлокодерство

И чем же? Осилишь объяснить не обосравшись?

carb_blog10 ()
Ответ на: комментарий от carb_blog10

да пошёл-бы ты по воду мил человек.

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

emulek ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.