Другие языки программирования и технологии

[C++] Зачем динамически выделять память под 1 переменную?

К примеру имеет смысл динамически выделить память для динамического массив
int *ar = new int[n];

Но зачем делать так?
int *a = new int;

Это как бы создание переменной через указатель? В чем проблема сделать так:
int a;
int *b = &a;

Объясните, пожалуйста
Для красоты и до кучи. В случае с типом int особо смысла-то и нету. А вот char* - уже совсем другое дело. Ну и void*. Как вы правильно сказали, проще сделать int a = 5; а в функцию передавать &a - адрес его
ЮШ
Юрий Шут
40 076
Лучший ответ
int *ar = new int[n]; // Здесь блок памяти из n элементов типа int в куче, а указатель на стеке (операция выделения памяти)
int *a = new int; // Здесь переменная в куче, а указатель на стеке (так делать не надо)
int *b = &a; // Здесь и переменная и указатель на стеке (операция взятия адреса)
int *a = new int;
может потом возвращают эту переменную через return и чтобы она существовала, конечно если удаляют в конце delete, то нет смысла, проще int a и использовать.
int *b = &a; // не присвоить другой адрес же
Нельзя взять адрес автоматической переменной, потому что это регистр процессора!
Адрес есть только:
1) у глобальных переменных;
2) переменных с ключевым словом static;
3) у массива байт выделенных из кучи (malloc/new).

Если тебе нужен адрес, то по-другому его и не взять.
У переменных с ключевым словом static свои проблемы. Дело в том, что статичное значение не меняется при вызове функции. Т. е. такая функция будет не thread safe. Например:

char* GetErrorMsg(int errno){
static char msg[256];
sprintf(msg," Error: %s. \n",tabbuf[errno]);
return(msg); }

Если такую функцию вызовут два (или более) потока одновременно, то они будут писать в один буфер и получат один и тот же указатель.

char* GetErrorMsg(int errno){
char *msg;
msg = new char[256];
sprintf(msg," Error: %s. \n",tabbuf[errno]);
return(msg); }

В последнем случае каждый поток при вызове функции получит свой буфер памяти и, соответственно, свой указатель! Теперь наша функция стала многопоточной! Однако, и она не лишена недостатков. Во-первых, оператор new медленный. Всего 10000 вызовов new или malloc поставят на колени даже современный i7. Во-вторых, и здесь мы целиком полагаемся на автоматически сборщик мусора (или не забываем вручную вызывать delete). Иначе память будет потихоньку утекать. В принципе, и первый, и второй подход имеют право на существование, каждый со своими ограничениями, Но, всё же лучше использовать буфер, выделенный заранее:

int GetErrorMsg(int errno, char *msg){
return(sprintf(msg," Error: %s. \n",tabbuf[errno]));
}
Игорь Волькис Чего эт нельзя взять адрес автоматической переменной? Автоматическая переменная обладает временем жизни в пределах блока кода и областью видимости в пределах него же. Больше ограничений я не припомню.

Если мы говорим об интелловской архитектуре, автоматическая память реализуется с помощью стека (при входе в функцию указатель на стек ставится ниже на смещение достаточное для хранения всех переменных), но да, компилятор может оптимизировать и хранить переменные в регистрах, более того можно (было?) подсказать компилятору использовать регистр модификатором register.

Но ни С ни С++ не запрещает нам отдать адрес локальной переменной функции за её пределы и возыметь этим undefined behaviour.
Обоснованно это может понадобиться лишь в том случае, когда переменная может изменять своё значение и эта переменная наблюдается из двух и более мест, но по какой-то причине мы не хотим использовать static.

В других случаях смысла делать инт с адресом на инт я не вижу.