С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
0 / 0 / 0
Регистрация: 07.06.2012
Сообщений: 18

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

15.11.2012, 20:27. Показов 1897. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток.
Пытаюсь разобраться с динамическим выделением память.

Суть:
Есть структура с двумя полями:
1. Указатель на Имя таблицы
2. Указатель на двумерный массив
Пользователь вводит необходимое количество структур[t], размерность матрицы [n][m], длину поля для имени таблицы[s].

Подскажите пожалуйста, правильно ли я выделяю память?

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
#include <stdio.h>
#include <conio.h>
#include <string.h>
 
#define NULL 0
 
typedef struct Table
{
    char *TblName;
    int **Matrix;
} table;
 
void main()
{
    int t,n,m,s;
 
    printf("Enter number of structures (T): ");
    scanf("%d",&t);                 //Вводим необходимое количество структур
    printf("Enter the length of the string for the name of the table (S): ");
    scanf("%d",&s);                 //Вводим размерность поля для названия таблицы
    printf("Enter the row count for the matrix (N): ");
    scanf("%d",&n);                 //Вводим количество столбцов
    printf("Enter the number of columns in the matrix (M): ");
    scanf("%d",&m);                 //Вводим количество строк
    printf("----------------------------------------------------------------\n");
 
    table *mas = NULL;              //Объявил указатель для массива структур table
    mas = new table[t];             //Выделил память для массива структур table[t] и записал адрес начала блока памяти в указатель mas
 
    char *TblName = NULL;           //Объявил указатель для массива table.TblName (имя таблицы - массив символов)
    TblName = new char[s*t];        //Выделил память для массива table[t].TblName[s*t] и записал адрес начала блока памяти в указатель TblName
 
    int **Matrix = NULL;            //Объявил указатель для двумерного массива table.Matrix
    Matrix = new int * [n];         //Выделил память для массива указателей 
    for(int i=0;i<n;i++)        
        Matrix[n] = new int [m];    //Выделил память для массива значений
 
 
    for(int i=0;i<n;i++)
        delete Matrix [i];          //Освободил память выделенную для массива значений
    delete [] Matrix;               //Освободил память выделенную для массива указателей
 
    delete [] TblName;              //Освободил память выделенную для массива имени таблицы
 
    delete [] mas;                  //Освободил память выделенную для массива структур
 
    _getch();
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.11.2012, 20:27
Ответы с готовыми решениями:

Распределение памяти. Динамическое выделение памяти
an-1 an-2 ... a2

Динамическое выделение памяти!
Программа должна читать с клавы число и имя(до 15 символов). Данные должны вводится в одной функции а выводится во второй. Сохранять данные...

Динамическое выделение памяти new
Доброго времени всем :) Недавно начал вникать в прелести c++, однако встретился с неприступной холодностью его и непониманием моих...

6
2393 / 1914 / 763
Регистрация: 27.07.2012
Сообщений: 5,558
15.11.2012, 21:00
Много ереси. По порядку:
1.
C++
1
2
    table *mas = NULL;              //Объявил указатель для массива структур table
    mas = new table[t];             //Выделил память для массива структур table[t] и записал адрес начала блока памяти в указатель mas
Тут ещё всё более-менее правильно. Правда можно было выделить память сразу при объявлении указателя:
C++
1
    table *mas = new table[t];
2.
C++
1
2
    char *TblName = NULL;           //Объявил указатель для массива table.TblName (имя таблицы - массив символов)
    TblName = new char[s*t];        //Выделил память для массива table[t].TblName[s*t] и записал адрес начала блока памяти в указатель TblName
Если бы не прочитал комментарии, то подумал бы, что и тут всё хорошо, но я их всё таки прочитал... Указатель для массива TblName у тебя уже объявлен в твоей структуре. Поэтому ты должен был сделать так:
C++
1
2
for (int i = 0; i < t; ++i)
    mas[i]->TblName = new char[s*t];
А ты же просто выделил память под массив char, не имеющий отношения к твоей структуре.
1
0 / 0 / 0
Регистрация: 07.06.2012
Сообщений: 18
15.11.2012, 21:03  [ТС]
Спасибо, сейчас буду пробовать исправляться
Просто только начал изучать этот раздел, поэтому так все плохо..
0
2393 / 1914 / 763
Регистрация: 27.07.2012
Сообщений: 5,558
15.11.2012, 21:06
3.
C++
1
2
3
    Matrix = new int * [n];         //Выделил память для массива указателей 
    for(int i=0;i<n;i++)        
        Matrix[n] = new int [m];    //Выделил память для массива значений
Тут к предыдущей проблеме добавилась опечатка: n вместо i.
Для твоей структуры:
C++
1
2
3
4
5
6
for (int j = 0; j < t; ++j)
{    
    mas[j]->Matrix = new int* [n];         //Выделил память для массива указателей 
    for(int i = 0; i < n; ++i)        
        mas[j]->Matrix[i] = new int[m];    //Выделил память для массива значений
}
Добавлено через 1 минуту
Ещё замечание:
C++
1
2
3
4
5
typedef struct Table
{
    char *TblName;
    int **Matrix;
} table;
Зачем тут typedef? Только путаницу вносит. Делай так:
C++
1
2
3
4
5
struct Table
{
    char *TblName;
    int **Matrix;
};
И используй Table вместо table;
1
0 / 0 / 0
Регистрация: 07.06.2012
Сообщений: 18
15.11.2012, 21:13  [ТС]
А еще такой вопрос, например если я имя таблицы сделаю фиксированное, например массив из char'ов в 10 элементов
C++
1
2
3
4
5
struct Table
{
    char *TblName[10];
    int **Matrix;
}
можно ли так делать? чтобы дальше не делать цикл для считывания имени таблицы а писать как нибудь вот так
C++
1
gets(mas[i].TblName);
0
2393 / 1914 / 763
Регистрация: 27.07.2012
Сообщений: 5,558
15.11.2012, 21:21
Тогда не так. Массив не указателей, а символов:
C++
1
2
3
4
5
struct Table
{
    char TblName[10];
    int **Matrix;
}
1
0 / 0 / 0
Регистрация: 07.06.2012
Сообщений: 18
15.11.2012, 23:07  [ТС]
В чем разница если писать доступ к элементу структуры через точку или через стрелку? Или стрелка это не доступ к элементу?

C++
1
2
3
4
5
6
7
8
9
10
struct Table
{
    char *TblName;
    int **Matrix;
};
 
Table *mas = new Table[t];
 
    for(int i=0; i<t; i++)
            mas[i].TblName = new char[10];
Добавлено через 21 минуту
Вот что у меня получилось.
Но есть две проблемы:
1. Например я ввожу что мне нужно 2 структуры, после чего ввожу имя первой таблицы, значения для первой таблицы, далее имя второй таблицы и ввод прерывается, перескакивает сразу на вывод.. И вывод значения даже первой структуры неверно... бред какой то....

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
#include <stdio.h>
#include <conio.h>
#include <string.h>
 
struct Table
{
    char *TblName;
    int **Matrix;
};
 
void main()
{
    int t,n,m,s;
 
    printf("Enter number of structures (T): ");
    scanf("%d",&t);                 //Вводим необходимое количество структур
    printf("Enter the row count for the matrix (N): ");
    scanf("%d",&n);                 //Вводим количество столбцов
    printf("Enter the number of columns in the matrix (M): ");
    scanf("%d",&m);                 //Вводим количество строк
    printf("----------------------------------------------------------------\n");
 
    Table *mas = new Table[t];
 
    for(int i=0; i<t; i++)
            mas[i].TblName = new char[6];
 
    for (int j=0;j<n;j++)
    {    
        mas[j].Matrix = new int *[n];         
        for(int k=0;k<n;k++)        
            mas[j].Matrix[k] = new int[m];   
    }
 
    printf("Enter information:\n");
 
    for(int i=0;i<t;i++)
    {
        printf("Entering information for the structure number [%d]:\n",i+1);
        printf("Enter the name of the table: \n");
        for(int j=0;j<6;j++)
            scanf("%c",&mas[i].TblName[j]);
        printf("Enter the values for the table[%d][%d]: \n",n,m);
        for(int k=0;k<n;k++)
            for(int g=0;g<m;g++)
                scanf("%d",&mas[i].Matrix[k][g]);
        printf("Entering information for the structure number [%d] completed!\n",i+1);
    }
 
    printf("Information output:\n");
 
    for(int i=0;i<t;i++)
    {
        printf("Output information for the structure number [%d]:\n",i+1);
        printf("Output the name of the table: \n");
        for(int j=0;j<6;j++)
            printf("%c",&mas[i].TblName[j]);
        printf("Output the values ​​for the table[%d][%d]: \n",n,m);
        for(int k=0;k<n;k++)
            for(int g=0;g<m;g++)
                printf("%d",&mas[i].Matrix[k][g]);
        printf("Output information for the structure number [%d] completed!\n",i+1);
    }
 
    _getch();
}
Добавлено через 1 час 21 минуту
Все сделал Спасибо большое за помощь.

Все вроде бы работает хорошо, только редко бывает такой глюк как я писал выше - не хочет считывать значения для второй матрицы а сразу перескакивает на вывод инфы.

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
#include <stdio.h>
#include <conio.h>
#include <string.h>
 
struct Table            //Объявил структуру из двух полей указателей 
{
    char *TblName;      //Указатель на имя таблицы
    int **Matrix;       //Указатель на двумерный массив
};
 
void main()
{
    int t,n,m;          //Объявил переменные
 
    printf("Enter number of structures (T): ");
    scanf("%d",&t);                 //Вводим необходимое количество структур
    printf("Enter the row count for the matrix (N): ");
    scanf("%d",&n);                 //Вводим количество столбцов
    printf("Enter the number of columns in the matrix (M): ");
    scanf("%d",&m);                 //Вводим количество строк
    printf("----------------------------------------------------------------\n");
 
    Table *mas = new Table[t];          //Выделил память для массива структур количеством t
 
    for(int i=0; i<t; i++)
            mas[i].TblName = new char[100];     //Выделил память для имени таблицы для каждой структуры
 
    for (int j=0;j<t;j++)
    {    
        mas[j].Matrix = new int* [n];           //Выделил память для массива указателей на двумерный массив
        for(int k=0;k<n;k++)        
            mas[j].Matrix[k] = new int[m];      //Выделил память для массива значений двумерного массива
    }
 
    printf("Enter information:\n");             //Блок ввода информации
 
    for(int i=0;i<t;i++)
    {
        printf("Entering information for the structure number [%d]:\n",i+1);
        printf("Enter the name of the table: \n");
            for(int j=0;j<100;j++)
            {
                scanf("%c",&mas[i].TblName[j]);
                if (mas[i].TblName[j]==' ') j=100;      //Считываю имя таблицы до первого пробела для текущей структуры
            }
        printf("Enter the values for the table[%d][%d]: \n",n,m);
        for(int k=0;k<n;k++)
            for(int g=0;g<m;g++)
                scanf("%d",&mas[i].Matrix[k][g]);       //Считываю значения для таблицы для текущей структуры
        printf("Entering information for the structure number [%d] completed!\n",i+1);
    }
 
    printf("Information output:\n");            //Блок вывода информации
 
    for(int i=0;i<t;i++)
    {
        printf("Output information for the structure number [%d]:\n",i+1);
        printf("Output the name of the table: ");
            for(int j=0;j<100;j++)
            {
                printf("%c",mas[i].TblName[j]);
                if (mas[i].TblName[j]==' ') j=100;      //Вывожу имя таблицы для текущей структуры
            }
        printf("\nOutput the values for the table[%d][%d]: \n",n,m);
        for(int k=0;k<n;k++)
        {
            for(int g=0;g<m;g++)
                printf("%d ",mas[i].Matrix[k][g]);      //Вывожу значения таблицы для текущей структуры
            printf("\n");
        }
        printf("Output information for the structure number [%d] completed!\n",i+1);
    }
        
    for (int j=0;j<t;j++)
    {      
        for(int k=0;k<n;k++)        
        {
            delete mas[j].Matrix[k];        //Освободил память занятую под массив значений матрицы
        }
        delete mas[j].Matrix;               //Освободил память занятую под массив указателей матрицы
        delete mas[j].TblName;              //Освободил память занятую под имена таблиц
    }
 
    delete [] mas;                          //И нахер удалил все структуры :)
    
    _getch();
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.11.2012, 23:07
Помогаю со студенческими работами здесь

Динамическое выделение памяти
Есть следующее объявление #include&lt;iostream&gt; #define MAX 1000 //======================= int arr; int arr2; int arr3; ...

Динамическое выделение памяти
Использовать динамическое выделение памяти для программы : #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;iomanip&gt; ...

Динамическое выделение памяти
есть код: int u = 0; char* mstrcat(char *str1, char *str2) { u = sizeof(str1); // *str1 = new char; char *res = str1; ...

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

Динамическое выделение памяти
Объясните пожалуйста.Не могу понять в чём разница между malloc,calloc/free и new/delete


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Old Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru