C/C++

Никак не могу понять применение операции NEW и DELETE.

Пусть у нас есть: link* a = new link;
Где link - структура. Можно было другой пример привести, но после одной программы меня реально это раздражать начало. Типо, я понимаю, NEW - это выделение памяти, а DELETE полностью удаляет содержимое, но все же, зачем? Обойтись же можно

p.s та самая программа, которая, казалось бы, вроде должна остаться без вопросов:

// linklist.cpp
// список
#include
using namespace std;
///////////////////////////////////////////////////////////
struct link // один элемент списка
{
int data; // некоторые данные
link* next; // указатель на следующую структуру
};
///////////////////////////////////////////////////////////
class linklist // список
{
private:
link* first;
public:
linklist ( ) // конструктор без параметров
{ first = NULL; } // первого элемента пока нет
void additem ( int d ); // добавление элемента
void display ( ); // показ данных
};
///////////////////////////////////////////////////////////
void linklist::additem ( int d ) // добавление элемента
{
link* newlink = new link; // выделяем память
newlink->data = d; // запоминаем данные
newlink->next = first; // запоминаем значение first
first = newlink; // first теперь указывает на новый элемент
}
///////////////////////////////////////////////////////////
void linklist::display ( )
{
link* current = first; // начинаем с первого элемента
while( current ) // пока есть данные
{
cout << current->data << endl; // печатаем данные
current = current->next; // двигаемся к следующему элементу
}
}
///////////////////////////////////////////////////////////
int main ( )
{
linklist li; // создаем переменную-список

li.additem ( 25 ); // добавляем туда несколько чисел
li.additem ( 36 );
li.additem ( 49 );
li.additem ( 64 );

li.display ( ); // показываем список

return 0;
}
Попробуйте решить эту задачу без динамического выделения памяти...

#include <iostream>
#include <random>
#include <iomanip>
using namespace std;
struct Dot {
double x;
double y;
double z;
};
int main() {
uniform_real_distribution<> urd(-100, 100);
mt19937_64 gen{ random_device()() };
int n = 10'000'000;
auto box = new (nothrow) Dot[n];
if (box != nullptr) {
for (auto i = 0; i < n; ++i) {
box[i].x = urd(gen);
box[i].y = urd(gen);
box[i].z = urd(gen);
}
auto a = 0., b = 0., c = 0.;
for (auto i = 0; i < n; ++i) {
a += box[i].x;
b += box[i].y;
c += box[i].z;
}
a /= n;
b /= n;
c /= n;
cout
<< fixed << setprecision(6)
<< setw(10) << a << '\n'
<< setw(10) << b << '\n'
<< setw(10) << c << '\n';
delete[] box;
}
system("pause > nul");
}
Кирилл Яковлев
Кирилл Яковлев
64 565
Лучший ответ
Да - можно обойтись. Но тогда ты ограничен фиксированным размером массива структур. Если ты сделаешь массив слишком маленьким - не сможешь решить часть задач. Если сделаешь слишком большим - это будет бессмысленный расход памяти.

Смысл new в том, что ты выделяешь участок памяти только тогда, когда он тебе реально понадобится.

И нет, delete НЕ очищает, а ОСВОБОЖДАЕТ память - так что следующий new может использовать память, освобождённую delete.
Се
Сергей
94 105
зачем нужен delete?
тут - ни за чем. программа завершается, память автоматически освобождается.

а вообще - если жизнь бурлит, подо что-то память выделяется, что-то перестаёт быть нужным - вот как раз delete и позволяет эту память возвращать.

это как с городом. если не сносить старые здания, а всё время ставить новые, получится... ну, тихий центр ^_^
RK
Rifkat Karimov
85 357
У тебя в голове каша.
Это, как правило, у всех, кто изучает язык не из первоисточников и не с того момента, с которого желательно.
Как говорилось в фильме "Матрица", всё должно возвращаться к первоисточнику:)
Иди к первоисточнику, к языку Си, почитай простенькие книжки по основам Си.
Чтобы понять, что к чему, и почувствовать мощь языка, нужно внимательно изучить азы, а не наставления тех, кто сам предлагает свой потребительский вариант "лёгкого языка", где думать особо не надо.
Виталий Коваль
Виталий Коваль
37 945
предположим, что мы пишем веб-сервер
вот упрощённый цикл, обрабатывающий запросы клиентов
while(true) {
linklist request = GetRequestTokens(socket);
auto response = ProcessRequestTokens(request);
Respond(socket, response);
}

после некоторого количества обработанных запросов такой сервер сожрёт всю память и сдохнет, потому что объект request класса linklist после каждой итерации уничтожается, оставляя за собой кучу выделенных узлов списка от уже удовлетворённого запроса юзера, которые теперь никак не освободить даже в теории, потому что указатель на голову списка мы потеряли
вывод: следите за динамически выделяемой памятью, пишите деструкторы (и не только, см. rule of three) и используйте санитайзеры