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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
DimaAvatar
0 / 0 / 0
Регистрация: 05.02.2014
Сообщений: 141
#1

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

05.06.2016, 18:08. Просмотров 429. Ответов 9
Метки нет (Все метки)

пытаюсь доканать динамические массивы (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;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.06.2016, 18:08
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Добавление памяти динамическому массиву (C++):

Поиск по динамическому массиву - C++
Задан целочисленный двумерный массив a из n строк и m столбцов. Найти номер последнего максимального значения среди нечетных (по значению)...

Доступ к динамическому массиву - C++
Первый раз столкнулся с такой фигней. Что происходит? #include &lt;iostream&gt; using namespace std; int main(int argc, char...

Переход от статического к динамическому массиву - C++
Есть некая структура some_struct. Необходимо перейти от статического массива этих структур some_struct *Table; к динамическому ...

Нужен урок по одномерном и двумерному динамическому массиву - C++
Нужен урок по одномерном и двумерному динамическому массиву

Создать функцию, добавляющую столбец двухмерному динамическому массиву - C++
Доброго времени суток, уважаемые форумчане! Помогите, пожалуйста, разобраться как написать функцию, удаляющую столбец двумерному...

Создать класс-шаблон, откладывающий выделение динамической памяти до первого реального обращения к массиву - C++
нужно создать класс-шаблон, который откладывает выделение динамической памяти до первого реального обращения к массиву также нужно ...

9
Vort_
186 / 186 / 52
Регистрация: 10.07.2012
Сообщений: 400
05.06.2016, 18:29 #2
Выглядит правильно.
Может, ошибка где-то в другом месте?
1
SergioO
95 / 184 / 63
Регистрация: 13.12.2015
Сообщений: 999
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() )
надо еще учесть правильное выравнивание памяти
1
DimaAvatar
0 / 0 / 0
Регистрация: 05.02.2014
Сообщений: 141
05.06.2016, 18:47  [ТС] #4
SergioO, что есть выравнивание памяти?
0
SergioO
95 / 184 / 63
Регистрация: 13.12.2015
Сообщений: 999
05.06.2016, 18:56 #5
Цитата Сообщение от DimaAvatar Посмотреть сообщение
что есть выравнивание памяти
это когда программная реализация соответствует аппаратной. как правило компилятор выравнивает за вас, те в ваши структуры компилятор добавляет всякие левые поля, например (условно говоря). в поисковике посмотрите.
1
DimaAvatar
0 / 0 / 0
Регистрация: 05.02.2014
Сообщений: 141
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... я чего то не понимаю? разве изначальный массив после копирования его элементов во временный и перед выделением памяти не надо удалить? но именно при таком подходе все работает.. хотя... я бьюсь об заклад, что везде меня учили обратному. Значит где то ... какая то ошибка в суждениях, ткните пальцем, если можно. Спасибо.
0
Вложения
Тип файла: txt goods.txt (172 байт, 1 просмотров)
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++.
1
DimaAvatar
0 / 0 / 0
Регистрация: 05.02.2014
Сообщений: 141
07.06.2016, 12:28  [ТС] #8
Vort_, не могли бы объяснить разницу между ними???
мое имхо :

my_array_check = new check_array;(выделить память под структуру check_array)
my_array_check = new check_array[1];(эм... то же самое ))) но только с явным указанием кол-ва - под одну структуру!)
0
Vort_
186 / 186 / 52
Регистрация: 10.07.2012
Сообщений: 400
07.06.2016, 12:42 #9
Могу дать ссылку на Хабр:
delete, new[] в C++ и городские легенды об их сочетании
1
DimaAvatar
0 / 0 / 0
Регистрация: 05.02.2014
Сообщений: 141
07.06.2016, 21:38  [ТС] #10
Vort_, в общем да, надо разбираться, чем и займусь сейчас, но по факту:
my_array_check = new check_array;
и
my_array_check = new check_array[1];

это два разных эм.. способа(?) еще раз спасибо. код поменял. все рабит. осталось понять что к чему
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.06.2016, 21:38
Привет! Вот еще темы с ответами:

Вопрос по динамическому полиморфизму - C++
Здравствуйте. Прочитал про статический и динамический полиморфизмы. Возник такой вопрос. Имеем код: #include &lt;iostream&gt; ...

Подскажите книжку по динамическому программированию. - C++
Доброго времени суток! Наткнулся на такое понятие, как динамическое программирование, горю желанием узнать больше. Пожалуйста,...

Адаптировать задачу по динамическому программированию на рекурсию - C++
Добрый день, написал код, решающий задачу динамическим программированием. Есть тот,кто сможет помочь с адаптацией ее под рекурсию? ...

Выделить в памяти 1024 ячейки по 8 байт и вывести их адреса(МИНИ менеджер памяти)) - C++
Вот тут появилась такая интересная задача: требуется сделать программу которая управляет 1024 ячейками памяти по 8 байт каждая. т.е. за...


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

Или воспользуйтесь поиском по форуму:
10
Yandex
Объявления
07.06.2016, 21:38
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru