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

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

Восстановить пароль Регистрация
 
sedoi_starik
1 / 1 / 0
Регистрация: 13.06.2013
Сообщений: 35
12.06.2014, 02:31     Динамическое выделение памяти для структуры в функции #1
Объясните не могу понять. На С++ пишу совсем недавно. Суть вопроса, при первом запуске программы происходит проверка на существование файла. Если файла нет то происходит инициализация, задается вопрос о количестве записей в базе.

В функции InitDB должно происходить выделение память. Но при выполнении компилятор ругается на "0x00000000 <Неправильный указатель>".

Или я не правильно это делаю?
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
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;
 
struct DBcar{
    char model[15];
    char colors[15];
    int years;
    int mileage;
};
int *pSizeDB;
DBcar *car;
 
void SaveDB(int szDB, DBcar *pDB);
void OpenDB(int szDB, DBcar *pDB);
int InitDB(DBcar *ptDB);
void ListDB(int &szDB, DBcar *pDB);
void InputDB(int szDB, DBcar *pDB);
void AddDB(int szDB, DBcar *pDB);
void DeleteDB(int szDB, DBcar *pDB);
void UpdateDB(int szDB, DBcar *pDB);
void FindDB(int szDB, DBcar *pDB, int fnd);
 
void ListDB(int &szDB, DBcar *pDB){
    cout<<szDB;
    for(int i=0;i<szDB;i++){
        cout<<pDB[i].model;
    }
}
 
int InitDB(DBcar *ptDB){
    int sizeDB;
    cout<<"Введите первоначальные данные.\n";
    cout<<"Размер базы данных: ";
    cin>>sizeDB;
    //delete [] ptDB;
    ptDB=new DBcar[sizeDB];
    for(int i=0;i<sizeDB;i++){
        *ptDB[i].model='\0';
        //*pDB[i].colors='\0';
        // pDB[i].years='\0';
        // pDB[i].mileage='\0';
    }
    cout<<"База проинициализирована.";
    //pSizeDB=&sizeDB;
    return sizeDB;
    //delete [] cars; НЕ ЗАБЫТЬ
}
 
void OpenDB(int szDB, DBcar *pDB){
    //int *psizeDB;
    int sDB;
    FILE *FH;
    FH = fopen("myfile.bin", "rb");
    if(FH==NULL) {
        cout<<"Файл не найден. Будет произведена инициализация базы данных.";
        //fclose(FH);
        sDB=InitDB(pDB);
        pSizeDB=&sDB;
    }
    else {
        cout<<"Открывается база данных.";
        cout<<'\n';
        //for(int i=0; i<szDB; i++){
        //  fread(&pDB[szDB], sizeof(pDB), 1, FH);
        //}
        //fclose(FH);
        cout<<"Загрузка завершена.";
    }
}
 
int main()
{
    //car=new DBcar[];
    setlocale(0,"");
    OpenDB(1,car);
    //cout<<*pSizeDB;
    ListDB(*pSizeDB,car);
    system("PAUSE");
    return 0;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
12.06.2014, 03:00     Динамическое выделение памяти для структуры в функции #2
В InitDB() ссылку на указатель нужно передавать.

Добавлено через 5 минут
В OpenDB() адрес локальной переменной сохраняете:
C++
1
2
3
4
5
6
       ...
       int sDB;
       ...
       sDB=InitDB(pDB);
       pSizeDB=&sDB;
       ...
sedoi_starik
1 / 1 / 0
Регистрация: 13.06.2013
Сообщений: 35
12.06.2014, 03:00  [ТС]     Динамическое выделение памяти для структуры в функции #3
то есть вот так InitDB(DBcar &ptDB)?
тогда как должно быть организовано выделение?
C++
1
2
3
4
5
6
7
8
9
10
11
12
int InitDB(DBcar &ptDB){
    int sizeDB;
    cout<<"Введите первоначальные данные.\n";
    cout<<"Размер базы данных: ";
    cin>>sizeDB;
    ptDB=new DBcar[sizeDB];<<<<<<<---тут как быть?
    for(int i=0;i<sizeDB;i++){
        *ptDB[i].model='\0';
    }
    cout<<"База проинициализирована.";
    return sizeDB;
}
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
12.06.2014, 03:02     Динамическое выделение памяти для структуры в функции #4
Цитата Сообщение от sedoi_starik Посмотреть сообщение
то есть вот так InitDB(DBcar &ptDB)?
Цитата Сообщение от alsav22 Посмотреть сообщение
ссылку на указатель
C++
1
int InitDB(DBcar*& ptDB);
Добавлено через 28 секунд
Цитата Сообщение от sedoi_starik Посмотреть сообщение
тогда как должно быть организовано выделение?
Так же, как и было.
sedoi_starik
1 / 1 / 0
Регистрация: 13.06.2013
Сообщений: 35
12.06.2014, 03:21  [ТС]     Динамическое выделение памяти для структуры в функции #5
ссылку на указатель нужно передавать во всех функциях?

Добавлено через 3 минуты
ООоо да, все гуд.)) Спасибо, я бы ща тупил бы до утра))

Добавлено через 5 минут
Блин опять ступор а как быть с ListDB?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
12.06.2014, 03:24     Динамическое выделение памяти для структуры в функции #6
Цитата Сообщение от sedoi_starik Посмотреть сообщение
ссылку на указатель нужно передавать во всех функциях?
Не обязательно. Нужно туда, где меняется само значение указателя, как в InitDB():
C++
1
ptDB=new DBcar[sizeDB];
Добавлено через 2 минуты
Цитата Сообщение от sedoi_starik Посмотреть сообщение
Блин опять ступор а как быть с ListDB?
Вот это исправили?
Цитата Сообщение от alsav22 Посмотреть сообщение
В OpenDB() адрес локальной переменной сохраняете:
sedoi_starik
1 / 1 / 0
Регистрация: 13.06.2013
Сообщений: 35
12.06.2014, 03:25  [ТС]     Динамическое выделение памяти для структуры в функции #7
в InitDB() в моем замысле как бы возвращает размер выделенной памяти.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
12.06.2014, 03:29     Динамическое выделение памяти для структуры в функции #8
int* pSizeDB зачем указателем сделана? Просто int сделайте.

Добавлено через 1 минуту
Цитата Сообщение от sedoi_starik Посмотреть сообщение
в InitDB() в моем замысле как бы возвращает размер выделенной памяти.
Это понятно, но вы присваиваете этот размер локальной переменной, адрес её сохраняете, но после выхода из функции её уже нет. Сделайте просто int SizeDB, и присваивайте этой переменной размер выделенной памяти (тут будет просто копирование).
C++
1
2
3
int SizeDB; // глобальная переменная (вместо int* pSizeDB)
...
SizeDB = InitDB(pDB); // в функции
sedoi_starik
1 / 1 / 0
Регистрация: 13.06.2013
Сообщений: 35
12.06.2014, 03:41  [ТС]     Динамическое выделение памяти для структуры в функции #9
Мне пора спать походу. Спасибо.

Добавлено через 10 минут
Ну и еще на последок глупый вопрос как поместить строку в *ptDB[i].model?
strcpy(*ptDB[i].model,"test");
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
12.06.2014, 03:52     Динамическое выделение памяти для структуры в функции #10
В OpenDB() указатель тоже нужно по ссылке передать, чтобы потом его использовать в main().
Приблизительно так:
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
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;
 
struct DBcar{
    char model[15];
    char colors[15];
    int years;
    int mileage;
};
int SizeDB = 0;
DBcar *car = NULL;
 
void SaveDB(int szDB, DBcar *pDB);
void OpenDB(int szDB, DBcar*& pDB);
int InitDB(DBcar*& ptDB);
void ListDB(DBcar *pDB);
void InputDB(int szDB, DBcar *pDB);
void AddDB(int szDB, DBcar *pDB);
void DeleteDB(int szDB, DBcar *pDB);
void UpdateDB(int szDB, DBcar *pDB);
void FindDB(int szDB, DBcar *pDB, int fnd);
 
void ListDB(DBcar *pDB){
    cout << SizeDB;
    for(int i=0;i < SizeDB;i++){
        cout << pDB[i].model;
    }
}
 
int InitDB(DBcar*& ptDB){
    int sizeDB;
    cout<<"Введите первоначальные данные.\n";
    cout<<"Размер базы данных: ";
    cin>>sizeDB;
    //delete [] ptDB;
    ptDB=new DBcar[sizeDB];
    for(int i=0;i<sizeDB;i++){
        *ptDB[i].model='\0';
        //*pDB[i].colors='\0';
        // pDB[i].years='\0';
        // pDB[i].mileage='\0';
    }
    cout<<"База проинициализирована.";
    //pSizeDB=&sizeDB;
    return sizeDB;
    //delete [] cars; НЕ ЗАБЫТЬ
}
 
void OpenDB(int szDB, DBcar*& pDB){
    //int *psizeDB;
    //int sDB;
    FILE *FH;
    FH = fopen("myfile.bin", "rb");
    if(FH==NULL) {
        cout<<"Файл не найден. Будет произведена инициализация базы данных.";
        //fclose(FH);
        SizeDB = InitDB(pDB);
        
    }
    else {
        cout<<"Открывается база данных.";
        cout<<'\n';
        //for(int i=0; i<szDB; i++){
        //  fread(&pDB[szDB], sizeof(pDB), 1, FH);
        //}
        //fclose(FH);
        cout<<"Загрузка завершена.";
    }
}
 
int main()
{
    //car=new DBcar[];
    setlocale(0,"");
    OpenDB(1, car);
    //cout<<*pSizeDB;
    ListDB(car);
    system("PAUSE");
    return 0;
}
Добавлено через 3 минуты
Цитата Сообщение от sedoi_starik Посмотреть сообщение
strcpy(*ptDB[i].model,"test");
C++
1
strcpy(ptDB[i].model, "test");
sedoi_starik
1 / 1 / 0
Регистрация: 13.06.2013
Сообщений: 35
12.06.2014, 11:41  [ТС]     Динамическое выделение памяти для структуры в функции #11
Как организовать вывод данных в ListDB() по 10 записей на экран? Например база имеет размер 20.
при вызове ListDB() пользователю предлогается нажать (N)Next следующая страница, а при нажатии (C) Cancel отменить.
sedoi_starik
1 / 1 / 0
Регистрация: 13.06.2013
Сообщений: 35
13.06.2014, 23:40  [ТС]     Динамическое выделение памяти для структуры в функции #12
А как прочитать файл до конца, подсчитав количество записанных туда структур?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
13.06.2014, 23:51     Динамическое выделение памяти для структуры в функции #13
Что нужно: количество структур в файле определить (для этого не обязательно читать весь файл), или прочитать все структуры из файла? Или то, и то, вместе?
Если то, и то: читаем по структуре, до конца файла, и считаем.
sedoi_starik
1 / 1 / 0
Регистрация: 13.06.2013
Сообщений: 35
14.06.2014, 00:09  [ТС]     Динамическое выделение памяти для структуры в функции #14
Мне надо до загрузки структуры из файла узнать количество данных (pSizeDB) что бы я потом мог загружать из файла нормально структуру.

Добавлено через 8 минут
количество структур в файле определить
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
14.06.2014, 00:18     Динамическое выделение памяти для структуры в функции #15
Структуры в бинарном режиме записаны? Определить размер файла в байтах, разделить на размер структуры. Размер файла: курсор в конец файла (fseek()), ftell() выдаст количество байтов в файле. Не забыть, после этого, вернуть курсор в начало файла.
http://www.cplusplus.com/reference/cstdio/
sedoi_starik
1 / 1 / 0
Регистрация: 13.06.2013
Сообщений: 35
14.06.2014, 13:19  [ТС]     Динамическое выделение памяти для структуры в функции #16
Тут нашел на форуме
long len,n,m=sizeof(Student);
fseek(datafile, 0, SEEK_END);
len = ftell(datafile);
n = len/m;
fseek(datafile,0,SEEK_SET);
Но у меня почему то получается на сотню больше. Я грешу вот на это:
fwrite(&pDB[i], sizeof(pDB), 100, pFile);
И я до сих пор не могу понять как правильно это число писать?

Добавлено через 26 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void OpenDB(int szDB, DBcar*& pDB){
    FILE * pFile;
    pFile = fopen("myfile.bin", "rb");
    if(pFile==NULL) {
        cout<<"Файл не найден. Будет произведена инициализация базы данных.";
        pSizeDB=InitDB(pDB);
    }
    else {
        cout<<"Открывается база данных.";
        cout<<'\n';
        pSizeDB=GetSizeStruct(car);
        pDB=new DBcar[pSizeDB];
        for(int i=0; i<pSizeDB; i++){
        fread(&pDB[i], sizeof(pDB), 100, pFile);
        }
        cout<<"Загрузка завершена.";
//      fclose(pFile);
    }
//  fclose(pFile);
}
C++
1
2
3
4
5
6
7
8
9
10
11
int GetSizeStruct(DBcar *pDB){
    FILE * pFile;
    pFile = fopen("myfile.bin", "rb");
    long len,n,m=sizeof(pDB);
    fseek(pFile, 0, SEEK_END);
    len = ftell(pFile);
    n = len/m/100;
    fseek(pFile,0,SEEK_SET);
    fclose(pFile);
    return n;
}
Добавлено через 1 минуту
не пойму почему у меня ошибка вылазит если я рассокентирую одну fclose(pFile) в функции OpenDB()

Добавлено через 12 часов 17 минут
Как добавлять новые данные не используя алгоритм сортировки

Добавлено через 2 минуты
Задание №2
При добавлении новой записи, запись должна добавляться в соответствии её алфавитного порядка
(Пример: Бд содержит:"Вася", "Петя", "Саша". Добавляем запись "Женя". В БД должно быть "Вася","Женя", "Петя","Саша").
В процессе добавления, удаления, изменения записей сортировка производиться не должна.
И при выводе на экрна то же.
sedoi_starik
1 / 1 / 0
Регистрация: 13.06.2013
Сообщений: 35
14.06.2014, 13:24  [ТС]     Динамическое выделение памяти для структуры в функции #17
cars_db_struct.rar
Вот исходник программы
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.06.2014, 14:05     Динамическое выделение памяти для структуры в функции
Еще ссылки по теме:

Указатели, функции и динамическое выделение памяти: вывести строки с неповторяющимися данными C++
C++ Динамическое выделение памяти для Вектора ( не STL)
Нужно немного переделать программу: использовать функции и динамическое выделение памяти C++

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

Или воспользуйтесь поиском по форуму:
sedoi_starik
1 / 1 / 0
Регистрация: 13.06.2013
Сообщений: 35
14.06.2014, 14:05  [ТС]     Динамическое выделение памяти для структуры в функции #18
Почему то не получается сделать вывод только заполненых данных.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void ListDB(int szDB, DBcar *&pDB){
    //cout<<"Tut"<<szDB;
    for(int i=0;i<szDB;i++){
        if(!pDB[i].model){
            cout<<"Марка: "<<pDB[i].model;
            cout<<" цвет " <<pDB[i].colors;
            cout<<" год выпуска: " <<pDB[i].years;
            cout<<" пробег: " <<pDB[i].mileage<<'\n';
        }else
        {
            
        }
    }
 
}
Добавлено через 24 минуты
Все разобрался, вот как надо:
C++
1
2
3
4
5
6
7
8
9
if(!pDB[i].model [0]){
            break;
        }else
        {
            cout<<"Марка: "<<pDB[i].model;
            cout<<" цвет " <<pDB[i].colors;
            cout<<" год выпуска: " <<pDB[i].years;
            cout<<" пробег: " <<pDB[i].mileage<<'\n';
        }
Yandex
Объявления
14.06.2014, 14:05     Динамическое выделение памяти для структуры в функции
Ответ Создать тему
Опции темы

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