Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.84/25: Рейтинг темы: голосов - 25, средняя оценка - 4.84
1 / 1 / 0
Регистрация: 12.04.2019
Сообщений: 48

Удаление динамической памяти из другой функции

10.03.2020, 18:17. Показов 4878. Ответов 15

Студворк — интернет-сервис помощи студентам
Можно ли удалить массив, находясь в другой функции?

По логике после delete [] мы пишем название переменное, т.е. адрес первого эл.
Следовательно раз в M мы передаём тот самый первый адрес, то удаляем именно эту динамическую память.
Поправьте, если где ошибся.

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

Пример программы:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int* fun();
 
void main()
{
   int* M;
   M = fun();
 
   delete[] M;
}
 
int* fun()
{
   int* z = new int[5];
   //Куча всяких вычислений
   return z;
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.03.2020, 18:17
Ответы с готовыми решениями:

Удаление динамической памяти
Всем здрасьте. Имеется вот такая структура. struct ModelType { DWORD FVF; IDirect3DVertexBuffer9* vertexBuffer; ...

Удаление динамической памяти
В книгах по С++ я читал про утечку памяти. Я решил создать программу, в которой будет выделаться 1 Гб памяти и не удаляться. Будучи...

Удаление new из динамической памяти
Здравствуйте, у меня есть следующее присвоение: sign->numb = new int; Мне нужно от него избавиться в конце программы, но delete...

15
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
10.03.2020, 18:21
Цитата Сообщение от Adm178 Посмотреть сообщение
Можно ли удалить массив, находясь в другой функции?
Можно удалять где угодно, если указатель валидный.
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
10.03.2020, 20:48
Цитата Сообщение от Adm178 Посмотреть сообщение
когда прога доходит до удаления возникает ошибка, а если удалить в родной fun функции, то все норм.
Что-то не так в твоём описании. Если при удалении возникает ошибка, то возможно память где-то портишь, или освобождаешь уже освобождённую.
0
1 / 1 / 0
Регистрация: 12.04.2019
Сообщений: 48
11.03.2020, 02:14  [ТС]
Собственно сам код, но отчего ошибка при удалении

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;
 
int *Vvod(int &n);
int *Mass (int n, int *M, int &T);
 
int main() 
{
    setlocale(LC_ALL,"Ru");
    int P = 0, n = 0, *M1, *M2, T = 0;
 
    M1 = Vvod (n);
    M2 = Mass (n, M1, T);
 
    delete[] M1;
    delete[] M2;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
 
int *Vvod(int &n)
{
    int *m = new int[n];
 
    while (n <= 0)
        {
            cout << "Введите размерность m: ";
            cin >> n;
        }
    cout << "\n";
    
    for (int i = 0; i < n; i++)
    {
        cout << "m[" << i << "] = ";
        cin >> *(m+i);
    }
    cout << "\n";
 
    return m;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void TT(int *m, int n, int &T, int &min);
 
int *Mass(int n, int *m, int &T)
{
    int min = 0;
    TT(m, n, T, min);
    if (T == 0)
        return 0;
    int *m2 = new int[T];
    cout << m2 << endl;
 
    int j = 0;
 
        for (int i = 0; i < n; i++)
        {
            if ((*(m+i) > 0) && (*(m+i) % 2 == 0))
            {
                *(m2+j) = *(m+i) * min;
                j++;
            }
        }
    return m2;
}
 
void TT(int *m, int n, int &T, int &min)
{
    min = *m;
    for (int i = 0; i < n; i++)
    {
        if ((*(m+i) > 0) && (*(m+i) % 2 == 0))
        {
            T++;
            if ((*(m+i) < min && min >= 2) || (min < 2))
                min = *(m+i);
        }
    }
}
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
11.03.2020, 04:06
Лучший ответ Сообщение было отмечено Adm178 как решение

Решение

Цитата Сообщение от Adm178 Посмотреть сообщение
C++
1
2
3
int *Vvod(int &n) 
{ 
    int *m = new int[n];
Нулевой размер памяти выделяешь. Думаешь, потом он будет автоматом расти?

Добавлено через 2 минуты
C++
1
2
3
4
5
6
7
8
9
    while (n <= 0)
    {
        cout << "Введите размерность m: ";
        cin >> n;
    }
    
    int *m = new int[n];
 
    cout << "\n";
1
1 / 1 / 0
Регистрация: 12.04.2019
Сообщений: 48
11.03.2020, 04:24  [ТС]
Цитата Сообщение от nd2 Посмотреть сообщение
Нулевой размер памяти выделяешь. Думаешь, потом он будет автоматом расти?
Исправил, теперь без ошибок завершается
Не в первый раз уже натыкаюсь, что если размер памяти отсутствует изначально или потом меняется, то происходит ошибка удаления. Почему в процессе увеличения массива его размерность не меняется? Это специально так сделали или просто недоработка?
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
11.03.2020, 04:32
Цитата Сообщение от Adm178 Посмотреть сообщение
Не в первый раз уже натыкаюсь, что если размер памяти отсутствует изначально или потом меняется, то происходит ошибка удаления.
Ошибка от того, что залазишь в невыделенную память.

Добавлено через 58 секунд
Цитата Сообщение от Adm178 Посмотреть сообщение
Почему в процессе увеличения массива его размерность не меняется?
Встречный вопрос: а почему размер выделенной памяти должен меняться?

Добавлено через 1 минуту
То, что делаешь через new[] - это ручное управление. Сколько выделил, столько и будет, хочешь изменить - выделяй новую память.

Добавлено через 2 минуты
Есть классы с автоматическим управлением памятью, например, std::vector, там размер выделенной памяти автоматически меняется, без твоего участия.
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12936 / 6803 / 1821
Регистрация: 18.10.2014
Сообщений: 17,215
11.03.2020, 04:39
Цитата Сообщение от Adm178 Посмотреть сообщение
Почему в процессе увеличения массива его размерность не меняется?
О каком "процессе увеличения массива" вы ведете речь? Где он у вас в коде? В С++ даже понятия такого нет. Массивы в С++ в принципе не могут "увеличиваться".

Если вам вдруг понадобилось "увеличить массив", вам придется собственными руками создать новый массив большего размера, перенести все данные из старого массива туда, а старый массив уничтожить. (Есть готовые библиотечные средства, которые сделают многое из этого за вас, но суть все равно остается та же.)
1
1 / 1 / 0
Регистрация: 12.04.2019
Сообщений: 48
11.03.2020, 04:57  [ТС]
Я кажется понял о чем вы

C++
1
2
3
4
5
6
7
int *f = new int[];//или int *f = new int[1]
 
for(int i = 0; i < 3; i++)
{
   cin >> *(f+i);
   cout << *(f+i);
}
Я до этого считал, что в проге наподобие этой я увеличиваю динамический массив. Но получается я просто захожу за пределы массива и заполняю свободную память? И такой код может привести к утечке данных?
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
11.03.2020, 05:03
Цитата Сообщение от Adm178 Посмотреть сообщение
Но получается я просто захожу за пределы массива и заполняю свободную память?
Почему свободную? Может и занятую.
Цитата Сообщение от Adm178 Посмотреть сообщение
И такой код может привести к утечке данных?
Такой код приводит к UB. И вот такое:
Цитата Сообщение от Adm178 Посмотреть сообщение
C++
1
cin >> *(f+i);
обычно так пишут (если нет специального условия в задании):
C++
1
cin >> f[i];
1
1 / 1 / 0
Регистрация: 12.04.2019
Сообщений: 48
11.03.2020, 05:09  [ТС]
Еще вопрос: что делает прога, если написать int *f = new int[], память динамически выделилась или нет?
Ведь размерность мы не указали
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
11.03.2020, 05:32
Цитата Сообщение от Adm178 Посмотреть сообщение
что делает прога, если написать int *f = new int[], память динамически выделилась или нет?
Ведь размерность мы не указали
По стандарту, если правильно помню, размер (хотя бы нулевой) должен быть указан (у меня, в студии такое не компилируется). Если выделен нулевой размер, то указатель валидный, но размер памяти нулевой, со всеми вытекающими.

Добавлено через 11 минут
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
О каком "процессе увеличения массива" вы ведете речь? Где он у вас в коде? В С++ даже понятия такого нет. Массивы в С++ в принципе не могут "увеличиваться".
Adm178, имеется ввиду, что называть то, что выделяется через new[], массивом, не совсем правильно (хотя тут бывают споры на эту тему), по крайней мере, это не имеет отношения к типу данных массив. Размер массива является составной частью его типа, и поэтому должен быть известен на этапе компиляции.

Добавлено через 6 минут
http://www.cyberforum.ru/cpp-b... ost9493574
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12936 / 6803 / 1821
Регистрация: 18.10.2014
Сообщений: 17,215
11.03.2020, 05:44
Цитата Сообщение от nd2 Посмотреть сообщение
называть то, что выделяется через new[], массивом, не совсем правильно (хотя тут бывают споры на эту тему), по крайней мере, это не имеет отношения к типу данных массив
С чего бы это вдруг? Спецификация языка ясно говорит, что new[] создает в динамической памяти именно объект типа массив. Доступа к конкретному типу создаваемого new[] объекта у вас, однако, нет. Поэтому "опровергнуть" это утверждение стандарта языка вы не можете.

Но зачем его опровергать? Если стандарт сказал что это массив - то пусть так и будет. Чем вам это мешает?

Цитата Сообщение от nd2 Посмотреть сообщение
http://www.cyberforum.ru/cpp-beginners/thread1524871.html#post9493574
Автор книги по ссылке хотел просто сказать, что результат new-expression имеет тип "указатель", а не тип "массив". Но то ли у самого автора получилась косноязычная чушь, то ли переводчик напортачил.

Особенно умилило: "Даже если для определения типа массива использовать псевдоним типа, оператор new не резервирует объект типа массива. И в данном случае резервируется массив, хотя часть [число] не видима."
1
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
11.03.2020, 17:21
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Автор книги по ссылке хотел просто сказать, что результат new-expression имеет тип "указатель", а не тип "массив". Но то ли у самого автора получилась косноязычная чушь, то ли переводчик напортачил.
Непохоже.
0
19497 / 10102 / 2461
Регистрация: 30.01.2014
Сообщений: 17,808
12.03.2020, 13:07
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Спецификация языка ясно говорит, что new[] создает в динамической памяти именно объект типа массив.
Вспомнил тут старый спор: Почему передача по ссылке не работает, только по указателю?
Прокомментируете? Читать можно начиная с сообщения по ссылке. Мне тогда не хватило терпения это обсудить до конца.
Я думаю не обязательно отвечать в той старой теме, т.к. вопрос относится и к этой.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12936 / 6803 / 1821
Регистрация: 18.10.2014
Сообщений: 17,215
12.03.2020, 22:13
Цитата Сообщение от DrOffset Посмотреть сообщение
Вспомнил тут старый спор: Почему передача по ссылке не работает, только по указателю?
Прокомментируете? Читать можно начиная с сообщения по ссылке. Мне тогда не хватило терпения это обсудить до конца.
Я думаю не обязательно отвечать в той старой теме, т.к. вопрос относится и к этой.
Мне, честно говоря, навскидку это тоже показалось неразрешимым противоречием, если исходить их того, что в С++ тип "массив" может иметь только константный размер. Я сам тоже так считал, вследствие чего стандартное описание поведения new[] вызывало у меня недоумение.

С одной стороны new[] обязан создавать именно массив, ибо далее мы будем обращаться к элементам этого массива при помощи адресной арифметики, которая определена именно и только для массивов. С другой стороны, что же это за массив такой, если его размер не является константой?

Однако, рассмотрев ситуацию поближе, я прихожу к выводу, что неправильно считать, что массив в С++ может иметь только константный размер. Похоже, что в языке С++ объект типа "массив" запросто может иметь неконстантный размер. Нигде в стандарте языка этого явно не запрещается. Требование константности размера есть, но оно располагается на существенно более высоком уровне: на уровне формирования описателей типов и объявлений. Язык запрещает вам описывать тип "массив неконстантного размера" и запрещает объявлять объекты типа "массив неконстантного размера".

То есть массивы неконстантного размера в С++ существуют и всегда существовали. Просто в языке не существует способа описать такой тип ("не существует способа" значит "формально запрещено") . Единственная лазейка, не подпадающая под этот запрет: это создание массива без его объявления, т.е. именно через new [].
3
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
12.03.2020, 22:13
Помогаю со студенческими работами здесь

Удаление структуры из динамической памяти
struct aTapeElement { char Operator; float Operand; aTapeElement *NextElement; }; Это кусок кода из 15-го урока книги...

Удаление динамической памяти в классе
В классе инициализирован объект при помощи new. Куда следует приписать delete для этого объекта, если класс используется на протяжении всей...

Удаление объекта, созданного в динамической памяти
Здравствуйте! Подскажите, пожалуйста, правильное решение такой проблемы (возможно, это и не проблема вовсе :) . Вот фрагмент кода: ...

Удаление вектора из области динамической памяти.
Всем привет! Прошу разъяснить. Как правильно удалить содержимое вектора? class Coordinate { public: Coordinate() {} int...

Выделение и удаление памяти, выделенной для динамической строки
Данная функция производит ввод и собственно контроль ввода (размер массива от 1 до 20, иначе должна выдавать ошибку; при вводе букв также...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru