Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

С++ выделение памяти new

username Профи (534), закрыт 1 год назад
так и не понял в чем разница между
int a[5];
и int* a = new int[5];
и так и так в обоих массивах выделены места под значения и в дальнейшем можно будет инициализировать любыми значениями, так же delete можно применить как к int a[5]; так и к int* a = new int[5];
в чем таки разница?
Лучший ответ
Николай Веселуха Высший разум (384109) 1 год назад
Память под статический массив по стандарту резервируется в программном стеке во время компиляции, который ограничен размером, как правило это два мегабайта, но может быть и больше. Память, которая резервируется под статические массивы в одной области видимости – суммируется, и это следует учитывать. Размер статического массива должен быть известен к началу компиляции. Во время выполнения программы изменить размер статического массива невозможно. Память, выделяемая под динамический массив выделяется непрерывным куском в куче и ограничена ресурсами оперативной памяти. Размер динамического массива можно изменять во время выполнения программы.

К ответу двумя этажами выше. Оператор new не является синтаксическим сахаром, так как в отличии от malloc (calloc, realloc) вызывает конструкторы объектов, ну а delete, в отличие от free – вызывает деструкторы. Операторы new, new[], delete и delete[] можно перегружать, создавая собственные аллокаторы. Это тема большая и сложная. Здесь подробнее об этом.

Память выделенная c использованием malloc (calloc, realloc) должна освобождаться вызовом free, а выделенная с использованием new (new[]), освобождается вызовом delete (delete[]). Освобождать память выделенную динамически следует обязательно, а указателю, по которому она была выделена следует присвоить nullptr (NULL). Перед вызовом delete (delete[]) либо free следует проверять указатель на существование
 if (ptr != nullptr) {
delete ptr;
ptr = nullptr;
}
 if (matrix != nullptr) { 
for (size_t i = 0; i < length; ++i) delete[] matrix[i];
delete[] matrix;
matrix = nullptr;
}
 if (ptr != NULL) { 
free(ptr);
ptr = NULL;
}
Память под статический массив освобождается автоматически после завершения блока кода в котором она была выделена.

Любые попытки непредусмотренного стандартом вызова malloc, calloc, realloc, new, new[], delete, delete[], free могут привести к неопределённому поведению
Батаев ДмитрийПросветленный (23296) 1 год назад
вопрошающему на заметку пользоваться ответом ИМЕННО ЭТИМ, потому как инфа правильная и полная
Сергей Гений (60521) Батаев Дмитрий, Не полная. Тут написано про автоматический массив под видом статического. Статический может весить гораздо больше размера стека.
Николай ВеселухаВысший разум (384109) 1 год назад
В системе Windows размер статического глобального массива не может превышать 0x7FFFFFFF байт. Это много, и это ни есть хорошо. ОЗУ, несмотря на её огромные размеры всегда находится во фрагментированном состоянии и не факт что на момент запуска процесса в системе имеется непрерывный кусок памяти под ваш массив. Особенно этим грешат пользовательские ОС, на серверных дела обстоят лучше, там память непрерывно дефрагментируется в процессе работы. А как сейчас, наши умельцы на 32-разрядные платформы устанавливают 64-разрядные системы, то с ОЗУ у них острый дефицит возникает ещё в момент запуска, какие там 500 мегабайт под массив? Отказ в запуске и месть, месть, месть!
Остальные ответы
Валек Журавлев Гуру (3400) 1 год назад
Наверно ни в чем. Типо кому как удобней писать. А лучше спроси у нейронки от яндекса она програмирование знает, что хочешь подскажет. ну или you ком так и называется еще какая то есть не помню но на них только английский язык
Def Гений (66667) 1 год назад
В первом случае память выделяется на стеке, во втором - в куче. В стеке по дефолту около 1 мб и его память предназначена для всяких мелких локальных переменных + вызова функций, а не для того, чтобы там хранили все данные программы

>delete можно применить как к int a[5];
Применение delete к стековому массиву - это неопределённое поведение и за такое даже по ушам давать мало.
usernameПрофи (534) 1 год назад
но почему тогда такое можно сделать (удалить массив из стека) раз не правильно? все пишут что отличие от статического в том что можно удалить delete, и пишут так будто статический нельзя удалить
Максим Уразов, ты не "удалишь массив из стека", ты вызовешь неопределённое поведение. Которое выразится в том, что где-то в другом месте программы что-то сломается, и ты хрен поймёшь, почему. Оставь C++ и изучай что-то попроще, пока из детской песочницы не вырастешь.
СергейГений (60521) 1 год назад
Не обязательно в стеке. Int a[5] может быть где угодно. Даже в куче, и тогда его можно удалить delet-ом.
Def Гений (66667) Сергей Степанов, обязательно на стеке на архитектуре х86/х64, на всех мэйнстримовых компиляторах, за исключением случая, как отметили в ответах ниже, что подобные массивы, объявленные вне функций окажутся статически размещёнными при компиляции в образе исполняемого файла в секции с именем наподобие DATA/.data/bss.
λ Искусственный Интеллект (263515) 1 год назад
 int a[5] // cтатический массив  

память для одномерного массива
выделяется при компиляции программы,
и по умолчанию заполняется нулями,
или указанными значениями.
 int b[5] = {1,2,3,4,5} // любые целые числа  

int* a = new int[5]; // динамический массив

память для динамического массива выделяется
при выполнении программы.
Поэтому размер исполнимого файла не
увеличивается.
Это актуально для больших массивов,
или массивов, размер которых
заранее неизвестен.

new - это в некотором роде синтаксический
сахар к классическим сишным функциям
alloc, malloc,
хотя механизм вполне удобный
Krab Bark Искусственный Интеллект (301013) 1 год назад
int *a=new int[5]; - массив можно создавать нужного размера по ходу выполнения функции и уничтожать во время ее работы.
int a[5] - массив создается при загрузке кода функции и не может быть в ней уничтожен. Зато его можно инициализировать при объявлении. delete к нему применять нельзя.
Кроме того, есть разница в максимально допустимой длине. Еще одна разница (последовательное или вразброс размещение подмассивов) появится, если перейти к многомерным массивам.
usernameПрофи (534) 1 год назад
-> можно создавать нужного размера по ходу выполнения функции и уничтожать во время работы программы.

статический тоже можно через delete снести

-> Зато его можно инициализировать при объявлении.

статический тоже можно инициализировать при объявлении
username Профи (534) Максим Уразов, т.е не статический
S.H.I. Оракул (73879) 1 год назад
Основное различие между int a[5] и int* a = new int[5] заключается в том, как память выделяется и освобождается. Когда вы объявляете int a[5], память для массива выделяется на стеке, а когда вы используете int* a = new int[5], память выделяется в куче.

Оператор delete используется для освобождения памяти, которая была выделена с помощью оператора new. Он не может использоваться для освобождения памяти, которая была выделена на стеке. Таким образом, вы можете использовать delete для освобождения памяти, которая была выделена с помощью int* a = new int[5], но не можете использовать его для освобождения памяти, которая была выделена с помощью int a[5].

Важно отметить, что когда вы используете оператор new для выделения памяти, это ваша ответственность как программиста освободить эту память с помощью оператора delete, когда она больше не нужна. Если вы не освободите эту память, это может привести к утечке памяти. В то же время, когда вы используете массивы, объявленные на стеке, такие как int a[5], память автоматически освобождается, когда массив выходит из области видимости.
usernameПрофи (534) 1 год назад
-> Оператор delete используется для освобождения памяти, которая была выделена с помощью оператора new. Он не может использоваться для освобождения памяти, которая была выделена на стеке.

почему у меня может удалить без ошибок?
S.H.I. Оракул (73879) Максим Уразов, В некоторых случаях программа может продолжать работать без ошибок, но это не гарантирует, что она будет работать правильно во всех случаях.
Сергей Гений (60521) 1 год назад
Все тут ошиблись.
int a[5] означает только 5 (4х (обычно) байтных) переменных расположенных непрерывно. То есть это просто одна большая переменная. И в зависимости от того где она обьявлена, она может быть либо автоматической либо глобальной либо динамической)

вот и int* a = new int[5]; //обратите особое внимание на запись int[5] - это и есть ваш a[5].
new разместит эту переменную где-то в динамической памяти.
int a[5]; вне функций или внутри но с пометкой static сделает ее глобальной.
В остальных случаях она (массивина эта) будет обычной автоматической переменной.

И вообще массивов не существует.
(есть еще только для чтения переменные, например строки текста (чем не массив)? И расположены они вообще в постоянной неизменяемой области памяти)
Похожие вопросы