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

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

12.06.2014, 02:31. Показов 1489. Ответов 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
5499 / 4894 / 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
5499 / 4894 / 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
5499 / 4894 / 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
5499 / 4894 / 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
5499 / 4894 / 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
5499 / 4894 / 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
5499 / 4894 / 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
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
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 . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru