Форум программистов, компьютерный форум CyberForum.ru

Добавление памяти динамическому массиву - C++

Восстановить пароль Регистрация
 
DimaAvatar
0 / 0 / 0
Регистрация: 05.02.2014
Сообщений: 134
05.06.2016, 18:08     Добавление памяти динамическому массиву #1
пытаюсь доканать динамические массивы (vector не предлагать, с ним все ок).
суть задачи. есть массив структур, возникает необходимость добавить памяти в динамический массив. но возникает дамп памяти, видимо где то не разобрался, гляньте пожалуйста где мб косяк?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void check::memmory_allocate(int&local_count){
    /*создаю временный массив и копирую туда данные изначального массива*/ 
    check_array *temp_array = new check_array[local_count]; 
    for (int i = 0;i<local_count;++i){
        temp_array[i]=my_array_check[i];
    }
    /*удаляю изначальный массив*/
    delete [] my_array_check;
   /*выделяю память для изначального массива*/
    my_array_check = new check_array[local_count+1];
    /*копирую данные из временного массива в изначальный (но увеличенный в размере)*/
    for (int i = 0;i<local_count;++i){
        my_array_check[i]=temp_array[i];
    }
    /*удаляю временный массив*/
    delete [] temp_array;
    ++local_count;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.06.2016, 18:08     Добавление памяти динамическому массиву
Посмотрите здесь:

Подскажите книжку по динамическому программированию. C++
Вопрос по динамическому полиморфизму C++
C++ Переход от статического к динамическому массиву
C++ Нужен урок по одномерном и двумерному динамическому массиву
C++ Создать класс-шаблон, откладывающий выделение динамической памяти до первого реального обращения к массиву
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Vort_
 Аватар для Vort_
186 / 186 / 52
Регистрация: 10.07.2012
Сообщений: 400
05.06.2016, 18:29     Добавление памяти динамическому массиву #2
Выглядит правильно.
Может, ошибка где-то в другом месте?
SergioO
 Аватар для SergioO
89 / 178 / 61
Регистрация: 13.12.2015
Сообщений: 968
05.06.2016, 18:36     Добавление памяти динамическому массиву #3
C
1
2
a = malloc(1000*sizeof(struct));
a = realloc(a, 2000*sizeof(struct));
самое простое и надежное, тк в Linux, например, существует системный вызов alloc и можно много всяких красивых конструкций придумывать типа ::, но закончится все одинаково - обращением к ядру ОС с alloc (если заглянуть в реализацию new, то там тот же malloc() )
надо еще учесть правильное выравнивание памяти
DimaAvatar
0 / 0 / 0
Регистрация: 05.02.2014
Сообщений: 134
05.06.2016, 18:47  [ТС]     Добавление памяти динамическому массиву #4
SergioO, что есть выравнивание памяти?
SergioO
 Аватар для SergioO
89 / 178 / 61
Регистрация: 13.12.2015
Сообщений: 968
05.06.2016, 18:56     Добавление памяти динамическому массиву #5
Цитата Сообщение от DimaAvatar Посмотреть сообщение
что есть выравнивание памяти
это когда программная реализация соответствует аппаратной. как правило компилятор выравнивает за вас, те в ваши структуры компилятор добавляет всякие левые поля, например (условно говоря). в поисковике посмотрите.
DimaAvatar
0 / 0 / 0
Регистрация: 05.02.2014
Сообщений: 134
06.06.2016, 20:30  [ТС]     Добавление памяти динамическому массиву #6
и все таки я буду просить помощи.
main.cpp
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <iostream>
#include <cstring>  // для операций над string
#include <string>
#include <fstream>  // для открытия и чтнния файла
 
#include "check.h"
 
 
using namespace std;
 
void choise_menu();
void stock();
void to_stock();
void out_stock();
void add_to_list(string&);
 
/*Программа производит поостой учет наличия товара на складе, а так же осуществлять внесение новых складских позиций
 * пока не реализованно измененине остатков (выдача или поступление уже имеющихся наменклатурных едениц
 */
int main (){
 
 
    setlocale(LC_ALL,"");
    for (int i=0;i<77;i++){
        cout<<"=";
    }
    cout<<"\n= Программа складского учета электротехнической продукции "
          "ООО Рога и копыта = ";
 
    cout<<"\n";
    for (int i=0;i<77;i++){
        cout<<"=";
    }
    cout<<"\n";
 
/*здесь я создаю объекты класса, вообще сама по себе идея очень глупая, и архитектура программы ущербна чуть более чем полностью,
 * поскольку для каждого нового вида товара необходимо заводить новый класс, но до этого я дошел уже слишком поздно, впрочем в версии
 * 2.0 я обязательно изменю это.*/
 
 
 
/*здесь я передаю по ссылке объекты в функции. по ссылке, т.к. нет необходимости создавать дополнительные копии этих объекто
 * равно как и не имею конструктора копирования, что однако так же планируеться в версии 2.0*/
 
    //choise_menu();
    check obj;
 
    cin.get();
    return 0;
}
/*здесь функция предалагает пользователю меню выбора и в зависимости от выбора происходит старт той или иной функции
 * проверка ввода значений отстутствует, если пользователь вводит что то не из предлаааемых пунктов - меню сново предалагеться к вводу*/
 
void choise_menu(){
    cout<<"Выберете пункт меню программы:\n 1-посмотреть остатки товара\n 2-поступление товара на склад\n 3-выдача товара со склада\n";
    string count;
    getline(cin, count);
    if (count == "1") stock();  //имхо в сравнение с такой конструкцие switch отдыхает
    else if(count == "2") to_stock();
    else if (count == "3") out_stock();
    else {cout<<"проверьте правильность ввода пункта меню \n";choise_menu();}
 
}
 
/*здесь мы создаем указатель на базовый класс gooвы (который может хранить адрес любого из классов наследников
 * коими и являються классы wire и switches) и чз указатель получаем доступ к методам этих классов и производим вывод в поток информации
хранящейся в текстовой файле, который выступает в качестве */
 
void stock(){
 
}
 
/* функция принимает от пользователя данные для записи их в "базу данных" - текстовый файл
 * */
 
void to_stock(){
    string temp,product, mark, model,amount;
    cout<<"Введите наименование продукта, марку, модель и колличество товара приходуемого на склад\n";
    cout<<"продукт (wire or switch)\n";
    getline(cin,product);
    if (product=="switch"||product=="wire"){
        cout<<"марка\n";
        getline(cin,mark);
        cout<<"модель\n";
        getline(cin,model);
        cout<<"колличество\n";
        getline(cin,amount);
        temp = product + ";" + mark + ";" + model + ";"+amount;
        //cout<<temp;
    }else {
       to_stock();
    }
 
    add_to_list(temp);
    choise_menu();
}
 
/*добавляем ранее полученные данные в файл*/
 
void add_to_list(string&temp){
    int count = 0;
    string str;
    string just_for_count;
    ifstream file;
    ofstream file_out;
 
    file.open("/home/dima/QT_CPP/for_st/goods.txt");//здесь указать свой путь к файлу
    if (!file.is_open()){
        cout<<"<База данных не обноруженна проверьте верность указания пути\n";
    } else {
        while (!file.eof()){
            getline(file,just_for_count);
            count++;
        }
    }
    file.close();
    file.clear();//без сброса флагов ошибок рабоать не будет
 
    str = to_string(count) + ";" + temp;
 
 
 
    file_out.open("/home/dima/QT_CPP/for_st/goods.txt", ios::app);//здесь указать свой путь к файлу
 
    if (!file_out.is_open()){
        cout<<"<База данных не обноруженна проверьте верность указания пути\n";
    } else {
       file_out<<str;
    }
    file_out<<"\n";
    file_out.close();
    file_out.clear();
 
}
/* это функция выдачи товара и соотвтетсввенно уменьшения товара хранящегося на складе, как вы видите, она пока не реалиована*/
void out_stock(){
 
}
check.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef CHECK_H
#define CHECK_H
#include <iostream>
using namespace std;
 
class check {
    struct check_array{
        string name;
        string model;
    }mymymy;
    check_array *my_array_check = nullptr;
    public:
    check();
    void take_data();
    void pars_string(string&, int&);
    bool check_up(string&,int&);
    void memmory_allocate(int&);
    ~check(){delete [] my_array_check;};
 
};
 
#endif // CHECK_H
check.cpp
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
#include <iostream>
#include <fstream>
 
#include "check.h"
 
using namespace std;
 
check::check (){
    /*здесь я выделяю память под один эллемент, т.к. реализую выделение памяти для динамчческого массива с последующим добавлением,
     * в реальности выделял бы память в зависимости от задачи и стррмился бы к компромиссу между затратами времени и затратами
     * памяти*/
    my_array_check  = new  check_array;
    take_data();
}
 
void check::take_data(){
    string str;
    int local_count = 1;
    ifstream file;
    file.open("/home/dima/QT_CPP/my_project/sklad/goods.txt");
    if (!file.is_open()){
        cout<<"please check adress your data base file";
    } else {
        while(!file.eof()){
            getline(file,str);
            pars_string(str,local_count);
        }
    }
    file.close();
    file.clear();
}
 
void check::pars_string(string& str,int&local_count){
    str = str.substr(str.find(';')+1);
    string temp = str.substr(0,str.find(';')).c_str();
    if (check_up(temp,local_count)){
        my_array_check[local_count-1].name =str.substr(0,str.find(';')).c_str();//add only new name
        str = str.substr(str.find(';')+1);
        my_array_check[local_count-1].model = str.substr(0,str.find(';')).c_str();
        cout<<my_array_check[local_count-1].name<<" "<<my_array_check[local_count-1].model<<"\n";
        memmory_allocate(local_count);
    }else {
 
    }
 
}
 
bool check:: check_up(string&temp,int &local_count){
    for (int i = 0; i<local_count;i++){
        if (my_array_check[i].name == temp)return false;
    }
    return true;
}
 
void check::memmory_allocate(int&local_count){
    check_array *temp_array = new check_array[local_count];
    for (int i = 0;i<local_count;++i){
        temp_array[i]=my_array_check[i];
    }
   // delete [] my_array_check;//воот она предательская строчка!
 
    my_array_check = new check_array[local_count+1];
 
    for (int i = 0;i<local_count;++i){
        my_array_check[i]=temp_array[i];
    }
    delete [] temp_array;
    ++local_count;
}
программа, ну типа складского учета. она на начальной стадии, на данном этапе программа должна открывать текстовый файл (который служит базой данных) и считывать оттуда данные (название (name) и модель (модель) в структуру которая потом является элементом массива структур (собственно говоря это и есть объект check).
особый интерес у меня вызывает строчка 60 в которой... эм, ну я сейчас приведу описание...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void check::memmory_allocate(int&local_count){
    /*создаю временный массив и копирую туда данные изначального массива*/ 
    check_array *temp_array = new check_array[local_count]; 
    for (int i = 0;i<local_count;++i){
        temp_array[i]=my_array_check[i];
    }
    /*удаляю изначальный массив*/
    delete [] my_array_check;
   /*выделяю память для изначального массива*/
    my_array_check = new check_array[local_count+1];
    /*копирую данные из временного массива в изначальный (но увеличенный в размере)*/
    for (int i = 0;i<local_count;++i){
        my_array_check[i]=temp_array[i];
    }
    /*удаляю временный массив*/
    delete [] temp_array;
    ++local_count;
}
программа не работала, считывала только первую строку текстового файла и все - дамп памяти, стал разбираться. закопался в программу valgrind.. она то и ткнула меня носом сюда. когда строчку комментирую - все ок - 0 error программа завершилась в кодом 0... я чего то не понимаю? разве изначальный массив после копирования его элементов во временный и перед выделением памяти не надо удалить? но именно при таком подходе все работает.. хотя... я бьюсь об заклад, что везде меня учили обратному. Значит где то ... какая то ошибка в суждениях, ткните пальцем, если можно. Спасибо.
Вложения
Тип файла: txt goods.txt (172 байт, 1 просмотров)
Vort_
 Аватар для Vort_
186 / 186 / 52
Регистрация: 10.07.2012
Сообщений: 400
07.06.2016, 05:55     Добавление памяти динамическому массиву #7
в check::check():
my_array_check = new check_array;
-->
my_array_check = new check_array[1];
new и new[] - это два разных оператора в C++.
DimaAvatar
0 / 0 / 0
Регистрация: 05.02.2014
Сообщений: 134
07.06.2016, 12:28  [ТС]     Добавление памяти динамическому массиву #8
Vort_, не могли бы объяснить разницу между ними???
мое имхо :

my_array_check = new check_array;(выделить память под структуру check_array)
my_array_check = new check_array[1];(эм... то же самое ))) но только с явным указанием кол-ва - под одну структуру!)
Vort_
 Аватар для Vort_
186 / 186 / 52
Регистрация: 10.07.2012
Сообщений: 400
07.06.2016, 12:42     Добавление памяти динамическому массиву #9
Могу дать ссылку на Хабр:
delete, new[] в C++ и городские легенды об их сочетании
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.06.2016, 21:38     Добавление памяти динамическому массиву
Еще ссылки по теме:

C++ Поиск по динамическому массиву
Доступ к динамическому массиву C++
C++ Адаптировать задачу по динамическому программированию на рекурсию

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

Или воспользуйтесь поиском по форуму:
DimaAvatar
0 / 0 / 0
Регистрация: 05.02.2014
Сообщений: 134
07.06.2016, 21:38  [ТС]     Добавление памяти динамическому массиву #10
Vort_, в общем да, надо разбираться, чем и займусь сейчас, но по факту:
my_array_check = new check_array;
и
my_array_check = new check_array[1];

это два разных эм.. способа(?) еще раз спасибо. код поменял. все рабит. осталось понять что к чему
Yandex
Объявления
07.06.2016, 21:38     Добавление памяти динамическому массиву
Ответ Создать тему
Опции темы

Текущее время: 14:57. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru