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

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

12.06.2014, 02:31. Показов 1583. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Объясните не могу понять. На С++ пишу совсем недавно. Суть вопроса, при первом запуске программы происходит проверка на существование файла. Если файла нет то происходит инициализация, задается вопрос о количестве записей в базе.

В функции 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;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.06.2014, 02:31
Ответы с готовыми решениями:

Структуры. Динамическое выделение памяти
Добрый день! Хочу задать следующий вопрос: typedef struct name { char *name; char *surename; } NAME; void main () { ...

Структуры и динамическое выделение памяти.
Привет, нужна помощь: есть написанная программа, которая работает со структурами, эту программу надо переписать так, чтобы она использовала...

Создайте динамическое выделение памяти в структуры
Есть код, нужно сделать динамическое выделение памяти в нем. #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;string&gt;...

17
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
12.06.2014, 03:00
В InitDB() ссылку на указатель нужно передавать.

Добавлено через 5 минут
В OpenDB() адрес локальной переменной сохраняете:
C++
1
2
3
4
5
6
       ...
       int sDB;
       ...
       sDB=InitDB(pDB);
       pSizeDB=&sDB;
       ...
0
1 / 1 / 2
Регистрация: 13.06.2013
Сообщений: 41
12.06.2014, 03:00  [ТС]
то есть вот так 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;
}
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
12.06.2014, 03:02
Цитата Сообщение от sedoi_starik Посмотреть сообщение
то есть вот так InitDB(DBcar &ptDB)?
Цитата Сообщение от alsav22 Посмотреть сообщение
ссылку на указатель
C++
1
int InitDB(DBcar*& ptDB);
Добавлено через 28 секунд
Цитата Сообщение от sedoi_starik Посмотреть сообщение
тогда как должно быть организовано выделение?
Так же, как и было.
1
1 / 1 / 2
Регистрация: 13.06.2013
Сообщений: 41
12.06.2014, 03:21  [ТС]
ссылку на указатель нужно передавать во всех функциях?

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

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

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

Добавлено через 10 минут
Ну и еще на последок глупый вопрос как поместить строку в *ptDB[i].model?
strcpy(*ptDB[i].model,"test");
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
12.06.2014, 03:52
В 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");
1
1 / 1 / 2
Регистрация: 13.06.2013
Сообщений: 41
12.06.2014, 11:41  [ТС]
Как организовать вывод данных в ListDB() по 10 записей на экран? Например база имеет размер 20.
при вызове ListDB() пользователю предлогается нажать (N)Next следующая страница, а при нажатии (C) Cancel отменить.
0
1 / 1 / 2
Регистрация: 13.06.2013
Сообщений: 41
13.06.2014, 23:40  [ТС]
А как прочитать файл до конца, подсчитав количество записанных туда структур?
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
13.06.2014, 23:51
Что нужно: количество структур в файле определить (для этого не обязательно читать весь файл), или прочитать все структуры из файла? Или то, и то, вместе?
Если то, и то: читаем по структуре, до конца файла, и считаем.
0
1 / 1 / 2
Регистрация: 13.06.2013
Сообщений: 41
14.06.2014, 00:09  [ТС]
Мне надо до загрузки структуры из файла узнать количество данных (pSizeDB) что бы я потом мог загружать из файла нормально структуру.

Добавлено через 8 минут
количество структур в файле определить
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
14.06.2014, 00:18
Структуры в бинарном режиме записаны? Определить размер файла в байтах, разделить на размер структуры. Размер файла: курсор в конец файла (fseek()), ftell() выдаст количество байтов в файле. Не забыть, после этого, вернуть курсор в начало файла.
http://www.cplusplus.com/reference/cstdio/
0
1 / 1 / 2
Регистрация: 13.06.2013
Сообщений: 41
14.06.2014, 13:19  [ТС]
Тут нашел на форуме
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
При добавлении новой записи, запись должна добавляться в соответствии её алфавитного порядка
(Пример: Бд содержит:"Вася", "Петя", "Саша". Добавляем запись "Женя". В БД должно быть "Вася","Женя", "Петя","Саша").
В процессе добавления, удаления, изменения записей сортировка производиться не должна.
И при выводе на экрна то же.
0
1 / 1 / 2
Регистрация: 13.06.2013
Сообщений: 41
14.06.2014, 13:24  [ТС]
cars_db_struct.rar
Вот исходник программы
0
1 / 1 / 2
Регистрация: 13.06.2013
Сообщений: 41
14.06.2014, 14:05  [ТС]
Почему то не получается сделать вывод только заполненых данных.
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';
        }
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.06.2014, 14:05
Помогаю со студенческими работами здесь

Динамическое выделение памяти в функции
Здравствуйте, столкнулся с такой проблемой: Нужно в функции считать из файла количество строк и столбцов, затем создать динамический...

Указатели и функции. Динамическое выделение памяти
1) Напишите программу, которая позволяет вводить динамический одно-мерный целочисленный массив и посредством вызова функции опреде-лять...

Динамическое выделение памяти внутри функции (что вернуть из функции, если не удалось выделить память?)
такое дело, есть функция, которая выполняет некоторую операцию, функция при успешном выполнении должна вернуть 0, при ниудачном код...

Указатели, функции и динамическое выделение памяти: вывести строки с неповторяющимися данными
Задана матрица A(n,n) ,n&lt;=15 . Написать программу, которая находит и выводит на экран номера тех строк, элементы которых не...

Нужно немного переделать программу: использовать функции и динамическое выделение памяти
Помогите переделать программу в соответствии с условиями: а) для хранения массивов используйте динамически распределяемую память; б)...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru