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

Освобождение и выделение динамической памяти

28.08.2014, 18:20. Показов 1618. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет народ, такой вопрос: Допустим в main, указателю выделил память, всё разумеется нормально, читаю пишу всё ок, потом передал этот указатель в функцию в другом файле (*.cpp), там освободил память и выделил другое количество, потом назад в main освободил. Можно ли так сделать? Спасибо.

Вот мои труды:

Файл 1:

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include"stdafx.h"
#include"iostream"
using namespace std;
typedef short unsigned su;
struct bd{
    char name[20], fam[20];
    su let;
};
void input(bd *b, su n, su s = -1);
void randomin(bd *bas, char **fam, su kf, char **name, su kn, su let, int kol);
int main(int argc,char *argv[]){
    setlocale(LC_ALL, "russian");
    int *k = new int;
    su *y = new su;
    if (argc == 1){
        cout << "Введите начальное колличество элементов пожалуйста: ";
        cin >> *k;
    }
    else{
        *k = atoi(argv[1]);
        *y = atoi(argv[2]);
 
    }
    bd *base = new bd[*k];
    if (argc == 3) goto consol;
    do{
        cout << "Выберите действия пожалуйста:\n0. Выход из программы.\n1. Изменить размер базы(с возможностью сохранения результатов).\n2. Отображениее данных всех субъектов.\n3. Заполнить случайными элементами.\n";
        cin >> *y;
        consol:
        switch (*y){
        case 0:{cout << "Всего доброго.\n Выполняю освобождение памяти...\n";
            delete[*k] base;
            delete k;
            cout << "Действия выполнены успешно. Программа завершена.\n";
            break;
        }
        case 1:{
                   cout << "Выбрано изменения размера базы. Сохранить Предыдущие результаты? 0/1\nВаш ответ: ";
                   bool v;
                   cin >> v;
                   if (v) {
                       cout << "Выполнено изменение размера с сохранение предыдущих результатов.\nВведите новый размер базы (не меньше " << *k << ").";
                       int l;
                       cin >> l;
                       if (*k > l) cout << "Невозможно сохранить предыдущие сведения, т.к. новая база меньше предыдущей.\nОтмена изменений...\n";
                       else{
                           cout << "Изменение размера базы и сохранение...\n";
                           input(base,l,*k);
                           *k = l;
                           cout << "Успех! Новый размер базы: " << *k << " элементов.\n";
                       }
                   }
                   else {
                       cout << "Введите новый размер базы пожалуйста: ";
                       cin >> *k;
                       input(base, *k);
                       cout << "\nУспех! Новый размер базы: " << *k << " элементов.\n";
                   }
                   break;
        }
        case 2:{
                   for (int i = 0; i < *k; i++){
                       cout << "Фамилия: " << (base + i)->fam;
                       cout << "\nИмя: " << (base + i)->name;
                       cout << "\nВозраст: " << (base + i)->let << "\nВсе данные отображены.\n";
                   }
                   break;
        }
        case 3:{
                   cout << "Выбрана функия заполнения случайными значениями.\n Использовать стандартную библиотеку или пользовательскую? 0/1";
                   bool v;
                   cin >> v;
                   if (v){
                       cout << "Выбрана пользовательская библиотека. Сколько Имён будем использовать?\nВаш ответ: ";
                       su name;
                       cin >> name;
                       cout << "Создаю пользовательскую библиотеку имён...\n";
                       char* *nmas = new char*[name];
                       for (su i = 0; i < name; i++)
                           *(nmas + i) = new char[20];
                       cout << "База имён создана, заполните её.\n\a";
                       for (su i = 0; i < name; i++){
                           cout << "Имя №" << i << ": ";
                           cin >> *(nmas + i);
                       }
                       cout << "Ваша база имён сохранена. Теперь фамилии.\nСколько фамилий будет в Вашей базе.?\nОтвет: ";
                       su fam;
                       cin >> fam;
                       cout << "Создаю базу фамилий...\n";
                       char* *fmas = new char*[fam];
                       for (su i = 0; i < fam; i++){
                           *(fmas+i) = new char[20];
                       }
                       cout << "База фамилий создана, заполните её.\n\a";
                       for (su i = 0; i < fam; i++){
                           cout << "Фамилия №" << i << ": ";
                           cin >> *(fmas + i);
                       }
                       cout << "Сколько максимум лет будет субъектам?\nОтвет: ";
                       su let;
                       cin >> let;
                       cout << "Заполняю базу...\n";
                       randomin(base, fmas, fam, nmas, name, let, *k);
                   }
        }
        case 4:{
 
        }
        default:cout << "Ошибка ввода!\n";
        }
    } while (*y);
    system("pause");
    return 0;
}
Файл 2:
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
#include"stdafx.h"
#include"iostream"
using namespace std;
typedef short unsigned su;
struct bd{
    char name[20], fam[20];
    su let;
};
void input(bd *b, su n, su s = -1);
void randomin(bd *bas, char **fam, su kf, char **name, su kn, su let, int kol);
 
void randomin(bd *bas, char **fam, su kf, char **name, su kn, su let, int kol){
    for (int i = 0; i < kol; i++){
        strcpy_s((bas + i)->fam, 20, *(fam + rand() % kf));
        strcpy_s((bas + i)->name, 20, *(fam + rand() % kn));
        (bas + i)->let = rand() % let;
    }
}
void input(bd *b, su n, su s){
    if (s == -1){
        delete[] b;
        b = new bd[n];
    }
    else{
        bd *temp = new bd[n];
        if (!temp) cout << "Не могу выделить пямять.\n";
        else{
            for (int i = 0; i < s; i++){
                strcpy_s((temp + i)->fam, 20, (b + i)->fam);
                strcpy_s((temp + i)->name, 20, (b + i)->name);
                (temp + i)->let = (b + i)->let;
            }
        }
        delete[] b;
        b = temp;
    }
}
Когда выбираю изменение размера базы и прыгаю во второй файл, то:

expression (L,"Buffer is too small")
for information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.

 Комментарий модератора 
Для вставки кода, используйте соответствующие теги!
Создавая темы, выбирайте более подходящий раздел на форуме.


Помогите пжл.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.08.2014, 18:20
Ответы с готовыми решениями:

Выделение и освобождение динамической памяти в функциях
Каким образом происходит выделение и очистка динамической памяти для массивов (в частности) в функциях? Написал код, но почему то ошибка...

Освобождение динамической памяти
Здравствуйте! Была задача реализовать сложение длинных чисел с помощью стеков. Сам стек реализовал просто, но всё же проблемы есть -...

Освобождение динамической памяти
Добрый день, объясните, пожалуйста, как правильно удалять выделенную динамическую память? Вот пример задачи, где массив произвольного...

6
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
28.08.2014, 18:29
Цитата Сообщение от lenchis001 Посмотреть сообщение
всё разумеется нормально, читаю пишу всё ок, потом передал этот указатель в функцию в другом файле (*.cpp), там освободил память и выделил другое количество, потом назад в main освободил. Можно ли так сделать?
при чем здесь Qt???
можно
но следить за указателями должен жестко, чуть зазевался и все, утечка памяти
0
1 / 1 / 0
Регистрация: 28.08.2014
Сообщений: 93
28.08.2014, 18:31  [ТС]
Господа, я только сегодня зарегистрировался и пока не особо в курсе как тут и что писать "взял что-то типа "новая тема" и всё", помоги просто решить проблему.
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
28.08.2014, 19:15
Цитата Сообщение от lenchis001 Посмотреть сообщение
strcpy_s((bas + i)->fam, 20, *(fam + rand() % kf));
вот это что?
0
1 / 1 / 0
Регистрация: 28.08.2014
Сообщений: 93
28.08.2014, 19:19  [ТС]
Тут идёт копирование в структуру случайной фамилии из массива фамилий, но проблема не в этом.
0
Модератор
Эксперт С++
 Аватар для zss
13766 / 10960 / 6490
Регистрация: 18.12.2011
Сообщений: 29,234
28.08.2014, 21:18
Лучший ответ Сообщение было отмечено lenchis001 как решение

Решение

Цитата Сообщение от lenchis001 Посмотреть сообщение
потом передал этот указатель в функцию в другом файле (*.cpp)
Передавать нужно АДРЕС этого указателя (или ссылку на указатель),
иначе передается копия адреса. После удаления памяти новая память выделится по другому адресу, а в вызывающей программе адрес останется прежним.
1
1 / 1 / 0
Регистрация: 28.08.2014
Сообщений: 93
29.08.2014, 01:05  [ТС]
Спасибо, я понял (даже не подумал по началу). Исправил, вот:
Файл 1:

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include"stdafx.h"
#include"iostream"
using namespace std;
typedef short unsigned su;
struct bd{
    char name[20], fam[20];
    su let;
};
void input(bd **b, su n, su s = -1);
void randomin(bd *bas, char **fam, su kf, char **name, su kn, su let, int kol);
int main(int argc, char *argv[]){
    setlocale(LC_ALL, "russian");
    int *k = new int;
    su *y = new su;
    if (argc == 1){
        cout << "Введите начальное колличество элементов пожалуйста: ";
        cin >> *k;
    }
    else{
        *k = atoi(argv[1]);
        *y = atoi(argv[2]);
    }
    bd *base = new bd[*k];
    if (argc == 3) goto consol;
    do{
        cout << "Выберите действия пожалуйста:\n0. Выход из программы.\n1. Изменить размер базы(с возможностью сохранения результатов).\n2. Отображениее данных всех субъектов.\n3. Заполнить случайными элементами.\n";
        cin >> *y;
    consol:
        switch (*y){
        case 0:{cout << "Всего доброго.\n Выполняю освобождение памяти...\n";
            delete[*k] base;
            delete k;
            cout << "Действия выполнены успешно. Программа завершена.\n";
            break;
        }
        case 1:{
                   cout << "Выбрано изменения размера базы. Сохранить Предыдущие результаты? 0/1\nВаш ответ: ";
                   bool v;
                   cin >> v;
                   if (v) {
                       cout << "Выполнено изменение размера с сохранение предыдущих результатов.\nВведите новый размер базы (не меньше " << *k << ").";
                       int l;
                       cin >> l;
                       if (*k > l) cout << "Невозможно сохранить предыдущие сведения, т.к. новая база меньше предыдущей.\nОтмена изменений...\n";
                       else{
                           cout << "Изменение размера базы и сохранение...\n";
                           input(&base, l, *k);
                           *k = l;
                           cout << "Успех! Новый размер базы: " << *k << " элементов.\n";
                       }
                   }
                   else {
                       cout << "Введите новый размер базы пожалуйста: ";
                       cin >> *k;
                       input(&base, *k);
                       cout << "\nУспех! Новый размер базы: " << *k << " элементов.\n";
                   }
                   break;
        }
        case 2:{
                   for (int i = 0; i < *k; i++){
                       cout << "Фамилия: " << (base + i)->fam;
                       cout << "\nИмя: " << (base + i)->name;
                       cout << "\nВозраст: " << (base + i)->let << "\nВсе данные отображены.\n";
                   }
                   break;
        }
        case 3:{
                   cout << "Выбрана функия заполнения случайными значениями.\n Использовать стандартную библиотеку или пользовательскую? 0/1";
                   bool v;
                   cin >> v;
                   if (v){
                       cout << "Выбрана пользовательская библиотека. Сколько Имён будем использовать?\nВаш ответ: ";
                       su name;
                       cin >> name;
                       cout << "Создаю пользовательскую библиотеку имён...\n";
                       char* *nmas = new char*[name];
                       for (su i = 0; i < name; i++)
                           *(nmas + i) = new char[20];
                       cout << "База имён создана, заполните её.\n\a";
                       for (su i = 0; i < name; i++){
                           cout << "Имя №" << i << ": ";
                           cin >> *(nmas + i);
                       }
                       cout << "Ваша база имён сохранена. Теперь фамилии.\nСколько фамилий будет в Вашей базе.?\nОтвет: ";
                       su fam;
                       cin >> fam;
                       cout << "Создаю базу фамилий...\n";
                       char* *fmas = new char*[fam];
                       for (su i = 0; i < fam; i++){
                           *(fmas + i) = new char[20];
                       }
                       cout << "База фамилий создана, заполните её.\n\a";
                       for (su i = 0; i < fam; i++){
                           cout << "Фамилия №" << i << ": ";
                           cin >> *(fmas + i);
                       }
                       cout << "Сколько максимум лет будет субъектам?\nОтвет: ";
                       su let;
                       cin >> let;
                       cout << "Заполняю базу...\n";
                       randomin(base, fmas, fam, nmas, name, let, *k);
                   }
        }
        case 4:{
 
        }
        default:cout << "Ошибка ввода!\n";
        }
    } while (*y);
    system("pause");
    return 0;
}
Файл 2:

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
#include"stdafx.h"
#include"iostream"
using namespace std;
typedef short unsigned su;
struct bd{
    char name[20], fam[20];
    su let;
};
void input(bd **b, su n, su s = -1);
void randomin(bd *bas, char **fam, su kf, char **name, su kn, su let, int kol);
 
void randomin(bd *bas, char **fam, su kf, char **name, su kn, su let, int kol){
    for (int i = 0; i < kol; i++){
        strcpy_s((bas + i)->fam, 20, *(fam + rand() % kf));
        strcpy_s((bas + i)->name, 20, *(fam + rand() % kn));
        (bas + i)->let = rand() % let;
    }
}
void input(bd **b, su n, su s){
    if (s == -1){
        delete[] *b;
        *b = new bd[n];
    }
    else{
        bd *temp = new bd[n];
        if (!temp) cout << "Не могу выделить пямять.\n";
        else{
            for (int i = 0; i < s; i++){
                strcpy_s((temp + i)->fam, 20, (*b + i)->fam);
                strcpy_s((temp + i)->name, 20, (*b + i)->name);
                (temp + i)->let = (*b + i)->let;
            }
        }
        delete[] *b;
        *b = temp;
    }
}
Но всё равно ошибка(

Добавлено через 31 минуту
Проблема почему-то в том, что программе не реагирует на аргумент по умолчанию, и всё время вызывает ложную ветвь.

Добавлено через 26 минут
Всё понял, "s" ведь типа su (short UNSIGNED), поэтому -1 трактовалось как 65535. Всё спасибо большое всем!)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.08.2014, 01:05
Помогаю со студенческими работами здесь

Освобождение динамической памяти в vs
Вообщем попался я тут, и так, код: //#define _CRT_SECURE_NO_WARNINGS добавить в vs #include &lt;iostream&gt; #include...

Освобождение динамической памяти
После первого вызова функции(при повторном) пишет ошибку. В функции sort один из элементов массива становится недоступным для чтения. Если...

Освобождение динамической памяти из-под прямоугольной матрицы
Добрый вечер! При попытке очищения памяти после завершения работы программы с прямоугольной матрицей m на n мне выдаёт ошибку а-ля...

Выделение и освобождение памяти
Доброго времени суток. Пишу класс по ООП, и назрел один вопрос, связанный с моментом выделения и освобождения памяти. class SOK { ...

Выделение и освобождение памяти в c++
Не давно наткнулся на такую замечательность : system(&quot;PAUSE&quot;);//1 раз int *p = new int; // память system(&quot;PAUSE&quot;);//2...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru