Почему Вы когда-либо хотели бы выделить память на "куче", а не стеке? [дубликат]

Позже версии GCC правильно реализуют стандарт.

стандарт определяет, что дисквалифицированные имена в шаблоне независимы и должны искаться, когда шаблон определяется. Определение зависимого базового класса неизвестно в то время (специализации шаблона базового класса могут существовать), таким образом, дисквалифицированные имена неспособны быть разрешенными.

Это верно и для имен переменной и для имен функций, объявленных в базовом классе.

, Как Вы заметили, решение состоит в том, чтобы обеспечить полностью определенное имя переменной или функции, или обеспечить объявление "использования". Например,

template<class T> 
int Bar<T>::Perna(int u) 
{ 
  int c = Foo<T>::a * 4; // This works
  c = this->a * 4; // and this

  using Foo<T>::a; 
  c = a * 4; // and with 'using', so should this
}

(я на самом деле не на 100% уверен в правильном синтаксисе для версии использования и не могу протестировать отсюда, но Вы получаете идею).

22
задан Community 23 May 2017 в 11:53
поделиться

9 ответов

Есть несколько причин:

  • Основная из них заключается в том, что при выделении кучи у вас больше всего гибкий контроль над временем жизни объекта (от malloc / calloc до free );
  • Пространство стека обычно является более ограниченным ресурсом, чем пространство кучи, по крайней мере в конфигурациях по умолчанию;
  • Отказ выделить пространство кучи можно аккуратно обработать, в то время как исчерпание пространства стека часто невозможно восстановить.

Без гибкого времени жизни объекта полезные структуры данных, такие как двоичные деревья и связанные списки, были бы фактически невозможно написать.

37
ответ дан 29 November 2019 в 03:35
поделиться
  1. Вы хотите, чтобы выделение оставалось за пределами вызова функции
  2. Вы хотите сохранить пространство стека (которое обычно ограничено несколькими мегабайтами)
  3. Вы работаете с перемещаемым память (Win16, базы данных и т. д.), или хотите восстановить после сбоев выделения.
  4. Длина переменной любой. Вы можете обманывать это, но ваш код будет действительно неприятным.

Большой - №1. Как только вы попадете в какой-либо вид параллелизма, или IPC # 1 повсюду. Даже самые нетривиальные однопоточные приложения сложно разработать без выделения некоторой кучи. Это практически имитирует функциональный язык C / C ++.

19
ответ дан 29 November 2019 в 03:35
поделиться

So I want to make a string. I can make it on the heap or on the stack. Let's try both:

char *heap = malloc(14);
if(heap == NULL)
  {
    // bad things happened!
  }
strcat(heap, "Hello, world!");

And for the stack:

char stack[] = "Hello, world!";

So now I have these two strings in their respective places. Later, I want to make them longer:

char *tmp = realloc(heap, 20);
if(tmp == NULL)
  {
    // bad things happened!
  }
heap = tmp;
memmove(heap + 13, heap + 7);
memcpy(heap + 7, "cruel ", 6);

And for the stack:

// umm... What?

This is only one benefit, and others have mentioned other benefits, but this is a rather nice one. With the heap, we can at least try to make our allocated space larger. With the stack, we're stuck with what we have. If we want room to grow, we have to declare it all up front, and we all know how it stinks to see this:

char username[MAX_BUF_SIZE];
8
ответ дан 29 November 2019 в 03:35
поделиться

Наиболее очевидное обоснование использования кучи - это когда вы вызываете функцию и вам нужно вернуть что-то неизвестной длины. Иногда вызывающий может передать блок памяти и размер функции, но в других случаях это просто непрактично, особенно если возвращаемый материал является сложным (например, набор различных объектов с летающими указателями и т. Д.).

4
ответ дан 29 November 2019 в 03:35
поделиться

just to add you can use alloca to allocate memory on the stack, but again memory on the stack is limited and also the space exists only during the function execution only. that does not mean everything should be allocated on the heap. like all design decisions this is also somewhat difficult, a "judicious" combination of both should be used.

0
ответ дан 29 November 2019 в 03:35
поделиться

Size limits are a huge dealbreaker in a lot of cases. The stack is usually measured in the low megabytes or even kilobytes (that's for everything on the stack), whereas all modern PCs allow you a few gigabytes of heap. So if you're going to be using a large amount of data, you absolutely need the heap.

3
ответ дан 29 November 2019 в 03:35
поделиться

Stack variables (often called 'automatic variables') is best used for things you want to always be the same, and always be small.

int x;
char foo[32];

Are all stack allocations, These are fixed at compile time too.

The best reason for heap allocation is that you cant always know how much space you need. You often only know this once the program is running. You might have an idea of limits but you would only want to use the exact amount of space required.

If you had to read in a file that could be anything from 1k to 50mb, you would not do this:-

int readdata ( FILE * f ) {
  char inputdata[50*1024*1025];
  ...
  return x;
}

That would try to allocate 50mb on the stack, which would usually fail as the stack is usually limited to 256k anyway.

0
ответ дан 29 November 2019 в 03:35
поделиться

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

0
ответ дан 29 November 2019 в 03:35
поделиться

Besides manual control of object's lifetime (which you mentioned), the other reasons for using heap would include:

  • Run-time control over object's size (both initial size and it's "later" size, during the program's execution).

For example, you can allocate an array of certain size, which is only known at run time.

With the introduction of VLA (Variable Length Arrays) in C99, it became possible to allocate arrays of fixed run-time size without using heap (this is basically a language-level implementation of 'alloca' functionality). However, in other cases you'd still need heap even in C99.

  • Run-time control over the total number of objects.

For example, when you build a binary tree stucture, you can't meaningfully allocate the nodes of the tree on the stack in advance. You have to use heap to allocated them "on demand".

  • Low-level technical considerations, as limited stack space (others already mentioned that).

When you need a large, say, I/O buffer, even for a short time (inside a single function) it makes more sense to request it from the heap instead of declaring a large automatic array.

0
ответ дан 29 November 2019 в 03:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: