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

Выделение динамической памяти - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
Faoxis
6 / 6 / 0
Регистрация: 11.04.2012
Сообщений: 114
12.06.2014, 20:26     Выделение динамической памяти #1
Чем
C++
1
2
    int *List = new int[10];
delete [] List;
отличается от обычного массива (int List[10]) ?

Нет, я понимаю, что создал динамическую переменную. Но ведь выделяется память на десять элементов как и в обычном массиве. Тогда зачем он нам нужен ?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.06.2014, 20:26     Выделение динамической памяти
Посмотрите здесь:

C++ матрица, выделение динамической памяти...
C++ Выделение динамической памяти
Выделение динамической памяти C++ C++
C++ выделение динамической памяти
Выделение динамической памяти C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Renji
1532 / 980 / 238
Регистрация: 05.06.2014
Сообщений: 2,950
12.06.2014, 20:34     Выделение динамической памяти #2
Нет, я понимаю, что создал динамическую переменную. Но ведь выделяется память на десять элементов как и в обычном массиве. Тогда зачем он нам нужен ?
Ни зачем он не нужен. Нужен int *List = new int[size]; (размер задается на стадии исполнения программы).
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
12.06.2014, 20:36     Выделение динамической памяти #3
Цитата Сообщение от Faoxis Посмотреть сообщение
Но ведь выделяется память на десять элементов как и в обычном массиве. Тогда зачем он нам нужен ?
int List[10] выделяет память на стеке,
int *List = new int[10] - выделяет память в куче.

Размер стека - несколько мегабайт, в зависимости от ОС и ключей компилятора. В нем размещаются локальные переменные, параметры и возвращаемые значения функций. Локальная переменная имеет ограниченную область существования. Размер кучи - порядка двух гигабайт в 32 битном приложении. Переменные в ней существуют до удаления.
Faoxis
6 / 6 / 0
Регистрация: 11.04.2012
Сообщений: 114
12.06.2014, 20:38  [ТС]     Выделение динамической памяти #4
а как это сделать ? в смысле size по умолчанию же не бывает...
Renji
1532 / 980 / 238
Регистрация: 05.06.2014
Сообщений: 2,950
12.06.2014, 20:41     Выделение динамической памяти #5
а как это сделать ? в смысле size по умолчанию же не бывает...
C++
1
2
3
4
int size;
cin>>size;
int *List = new int[size];
delete[]List;
Разумеется, дальнейшие манипуляции с size размера List не изменят.
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
12.06.2014, 20:43     Выделение динамической памяти #6
Цитата Сообщение от Faoxis Посмотреть сообщение
в смысле size по умолчанию же не бывает...
С++11 позволяет динамические массивы на стеке.

C++
1
2
3
4
int size = 10;
int array[size];
на куче 
int *dyn_array = new int[size];
Renji
1532 / 980 / 238
Регистрация: 05.06.2014
Сообщений: 2,950
12.06.2014, 20:50     Выделение динамической памяти #7
С++11 позволяет динамические массивы на стеке.
C99 позволяет динамические массивы на стеке. И компиляторы которые в C++11 поддерживают фишки C99.
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
12.06.2014, 20:58     Выделение динамической памяти #8
Цитата Сообщение от Renji Посмотреть сообщение
C99 позволяет динамические массивы на стеке. И компиляторы которые в C++11 поддерживают фишки C99.
Да, сорри, опечатка.
Faoxis
6 / 6 / 0
Регистрация: 11.04.2012
Сообщений: 114
13.06.2014, 10:14  [ТС]     Выделение динамической памяти #9
Смысл в том, что мне надо сделать реализацию списка в двух вариантах: используя статический массив и используя динамические переменные.

Статический вариант я сделал:

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
139
140
141
142
143
144
145
146
147
#include <iostream>
using namespace std;
 
short int i = 0;
/////////////////////////////////////////////////////////////////////////////////
 
 
void add(int mass[10]); // Добавление элемента в список
void search(int mass[10]); // Поиск элемента в списке
void del(int mass[10]); // Удаление элемента из списка
void output(int mass[10]); // Вывод списка на экран для проверки
 
 
 
//.................................................................................
int main()
{
    int List[10];
    
    for (int j = 0; j < 10; j++)
        List[j] = 0;
 
        cout << "Enter \'a\' if you want to add element at the list" << endl;
        cout << "Enter \'d\' if you want to delete element at the list" << endl;
        cout << "Enter \'s\' if you want to add element at the list" << endl;
        cout << "Enter \'c\' if you want to chek elements at the list" << endl;
        cout << "Enter \'b\' if you want to stop working program" << endl << endl;
 
 
    while(1 == 1)
    {
        cout << endl;
        cout << "Right here: ";
 
        char chek;
        cin >> chek;
 
        switch(chek)
        {
            case 'a':   add(List); break;
            case 'd':   del(List); break;
            case 's':    search(List); break;
            case 'c':   output(List); break;
            case 'b':   return 0;
        }
 
    }
 
    return 0;
}
//.................................................................................
 
 
 
//..................................................
void add(int mass[10])
{
    if (i < 10)
    {
        cout << "Enter data ";
 
        int push;
        cin >> push;
 
        mass[i] = push;
 
        i++;
    }
    else
        cout << "The list is full!";
 
    cout << endl;
}   
 
 
//..................................................
void del(int mass[10])
{
    if (i  > 0)
    {
        short int replace;
        replace = i;
 
        for(replace; replace < 9; replace++)
        {
            mass[replace-1] = mass[replace];
        }
 
        mass[9] = 0;
 
        i--;
    }
    else
        cout << "The list is empty!";
 
    cout << endl;
}   
 
 
 
 
 
 
 
//..................................................
void search(int mass[10])
{
    if (i < 10)
    {
        int ForSearch = 0;
        cout << "Enter data for searching:  ";
 
        cin >> ForSearch;
        cout << "Thanks!" << endl;
 
 
        for(short int j = 0; j < 10; j++)
        {
            if(mass[j] == ForSearch)
                cout << "The data " << ForSearch << " has namber " << j+1 << " at our list;" << endl;
        }
 
    }
    else
        cout << "The list is full!";
        
}   
 
 
//..................................................
void output(int mass[10])
{
    cout << endl;
 
    for(int j = 0; j  < 5; j++)
    {
        cout << "number " << j+1 << " is " << mass[j] << " ";
    }
    cout << endl;
 
    for(int j = 5; j  < 10; j++)
    {
        cout << "number " << j+1 << " is " << mass[j] << " ";
    }
    cout << endl << endl;
 
}


И вот думаю как делать то же самое, используя динамические переменные. На одному сайте прочел сообщение примерно следующего содержания: "Для постепенного выделения памяти используется команда ->". Я думаю, этот вариант будет лучшим. Не мог бы кто-нибудь объяснить как пользоваться оператором "->" каким - нибудь простым примером с комментариями ? Спасибо!
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
13.06.2014, 10:52     Выделение динамической памяти #10
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
С++11 позволяет динамические массивы на стеке.
Цитата Сообщение от Renji Посмотреть сообщение
И компиляторы которые в C++11 поддерживают фишки C99.
VLA нет в C++11, и в C++14 от него, вроде бы, тоже пока отказались. Пока это можно отнести к расширению gcc для C++. Так что и к поддержке C99 в плюсах это отношения не имеет. Кстати, в С11 (без ++) поддержка VLA стала опциональной, а не обязательной.

Цитата Сообщение от Faoxis Посмотреть сообщение
Смысл в том, что мне надо сделать реализацию списка в двух вариантах: используя статический массив и используя динамические переменные.
Смысл в том, что если говорить о связном списке, то статический массив тут вообще не помощник, т.к. список - разряженная структура, т.е. его элементы разбросаны по памяти, а не находятся в одном непрерывном участке. Если под списком понимается что-то другое - уточните постановку задачи.
Faoxis
6 / 6 / 0
Регистрация: 11.04.2012
Сообщений: 114
13.06.2014, 10:56  [ТС]     Выделение динамической памяти #11
Вот задача полностью (Delphi я не знаю):

Кликните здесь для просмотра всего текста
Список – упорядоченный набор данных одного типа. Отличается от массива тем, что имеет переменное число элементов.
Список из n элементов --------------------------------->
Список может быть реализован 2-мя способами:
1. на основе статических структур (массивов);
2. на основе динамических переменных.
Пример объявления списка:
1. на основе статических структур:
type
TList = record
| DATA_ENTRIES : тип;
end;
var
List : array [1..N] of TList; {массив, N=const }
SIZE : integer; { , указывает текущий размер}
… {базовые операции}

2. на основе динамических переменных:
type
PTR = ^TList; {новое поле данных имеющий тип указателя на TList }
TList = record
| DATA_ENTRIES : тип;
| NPTR : PTR {указатель на начало списка}
end;
var
LIST_HEAD : PTR; {указатель, который может указывать на начало ( или конец) списка}.

Обращение к элементам списка, созданного первым способом:
List[1].DATA_ENTRIES;
List[2].DATA_ENTRIES;

List[N].DATA_ENTRIES;
Обращение к элементам списка, созданного вторым способом:
List_HEAD^.DATA_ENTRIES; - обращение к I-ому элементу
List_HEAD^.NPTR^.DATA_ENTRIES; - ко II-ому элементу
List_HEAD^.NPTR^. NPTR^.DATA_ENTRIES;


Это однонаправленный ( односвязный) список – можно перемещаться только вперед.
Процедуры для динамического списка:
Исходная структура списка:
type
NameStr=string[15];
Link=^Student
Student=record
Name:NameStr;
Mark:integer;

Next:Link;
end;
var
First:Link;

Создание и инициализация динамической переменной:
var
P:Link;

New(P); {создали элемент списка}
{инициализируем элемент списка}
P^.Name:=’Иванов’;
P^.Mark:=5;

P^.Next:=nil; {пустой указатель}

Процедура добавления элемента в начало списка:
procedure AddFirst(A:Link);
{А-указатель на добавляемый элемент}
begin
A^.Next:=First;
First:=A;
end;

Процедура добавления элемента в произвольное место списка:
procedure AddAfter(A,Old:Link);
begin
a^.Next:=Old^.Next; {(1) А-указатель на добавляемый элемент}
Old^.Next:=A; {(2) Old-указатель на элемент списка, за которым
добавляется элемент}
end;

Удаление элемента из начала списка:
procedure DelFirst(var A:Link);
begin
A:=First; {сохраняем указатель на удаляемый элемент}
First:=First^.Next;
end;


Удаление элемента из произвольного места списка:
procedure DelAfter(Old:Link;Var A:Link);
begin
A:=Old^.Next; {сохраняем указатель на удаляемый элемент}
Old^.Next:=Old^.Next^.Next
end;


Поиск элемента:
function FindName(FN:NameStr):Link; {ф-ция возвращает указатель (Link) на найденный элемент}
var Curr:Link; {Curr – указатель на текущий элемент списка }
begin
Curr:=First;
While Curr<>nil do
If Curr^.Name=FN then
begin
FindName:=Curr; {возвращает указатель на найденный
Exit; элемент}
end;
else
Curr:=Curr^.Next;
FindName:=nil; {элемент не найден}
end;
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
13.06.2014, 10:57     Выделение динамической памяти #12
Цитата Сообщение от Faoxis Посмотреть сообщение
На одному сайте прочел сообщение примерно следующего содержания: "Для постепенного выделения памяти используется команда ->".
Можно ссылку на сайт? Оператор -> это обращение к объекту по указателю, он память не выделяет.
Динамические массивы в стандартной библиотеке - vector, у него есть методы и для вставки и для удаления.
Можно делать на динамических массивах в стиле C - перевыделять память под массив при добавлении и копировать в расширенный массив содержимое старого.
Faoxis
6 / 6 / 0
Регистрация: 11.04.2012
Сообщений: 114
13.06.2014, 10:58  [ТС]     Выделение динамической памяти #13
Вот задание полностью (Delphi я не знаю):

Кликните здесь для просмотра всего текста
Список – упорядоченный набор данных одного типа. Отличается от массива тем, что имеет переменное число элементов.
Список из n элементов --------------------------------->
Список может быть реализован 2-мя способами:
1. на основе статических структур (массивов);
2. на основе динамических переменных.
Пример объявления списка:
1. на основе статических структур:
type
TList = record
| DATA_ENTRIES : тип;
end;
var
List : array [1..N] of TList; {массив, N=const }
SIZE : integer; { , указывает текущий размер}
… {базовые операции}

2. на основе динамических переменных:
type
PTR = ^TList; {новое поле данных имеющий тип указателя на TList }
TList = record
| DATA_ENTRIES : тип;
| NPTR : PTR {указатель на начало списка}
end;
var
LIST_HEAD : PTR; {указатель, который может указывать на начало ( или конец) списка}.

Обращение к элементам списка, созданного первым способом:
List[1].DATA_ENTRIES;
List[2].DATA_ENTRIES;

List[N].DATA_ENTRIES;
Обращение к элементам списка, созданного вторым способом:
List_HEAD^.DATA_ENTRIES; - обращение к I-ому элементу
List_HEAD^.NPTR^.DATA_ENTRIES; - ко II-ому элементу
List_HEAD^.NPTR^. NPTR^.DATA_ENTRIES;


Это однонаправленный ( односвязный) список – можно перемещаться только вперед.
Процедуры для динамического списка:
Исходная структура списка:
type
NameStr=string[15];
Link=^Student
Student=record
Name:NameStr;
Mark:integer;

Next:Link;
end;
var
First:Link;

Создание и инициализация динамической переменной:
var
P:Link;

New(P); {создали элемент списка}
{инициализируем элемент списка}
P^.Name:=’Иванов’;
P^.Mark:=5;

P^.Next:=nil; {пустой указатель}

Процедура добавления элемента в начало списка:
procedure AddFirst(A:Link);
{А-указатель на добавляемый элемент}
begin
A^.Next:=First;
First:=A;
end;

Процедура добавления элемента в произвольное место списка:
procedure AddAfter(A,Old:Link);
begin
a^.Next:=Old^.Next; {(1) А-указатель на добавляемый элемент}
Old^.Next:=A; {(2) Old-указатель на элемент списка, за которым
добавляется элемент}
end;

Удаление элемента из начала списка:
procedure DelFirst(var A:Link);
begin
A:=First; {сохраняем указатель на удаляемый элемент}
First:=First^.Next;
end;


Удаление элемента из произвольного места списка:
procedure DelAfter(Old:Link;Var A:Link);
begin
A:=Old^.Next; {сохраняем указатель на удаляемый элемент}
Old^.Next:=Old^.Next^.Next
end;


Поиск элемента:
function FindName(FN:NameStr):Link; {ф-ция возвращает указатель (Link) на найденный элемент}
var Curr:Link; {Curr – указатель на текущий элемент списка }
begin
Curr:=First;
While Curr<>nil do
If Curr^.Name=FN then
begin
FindName:=Curr; {возвращает указатель на найденный
Exit; элемент}
end;
else
Curr:=Curr^.Next;
FindName:=nil; {элемент не найден}
end;
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
13.06.2014, 10:59     Выделение динамической памяти #14
Цитата Сообщение от Tulosba Посмотреть сообщение
Пока это можно отнести к расширению gcc для C++.
У Микрософта компилятор 16.00.30319.01 тоже VLA вполне себе понимает.
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
13.06.2014, 11:10     Выделение динамической памяти #15
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
У Микрософта компилятор 16.00.30319.01 тоже VLA вполне себе понимает.
Пример можно, который в 2010 студии работает?
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
13.06.2014, 11:13     Выделение динамической памяти #16
Цитата Сообщение от Tulosba Посмотреть сообщение
Пример можно, который в 2010 студии работает?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <clocale>
using namespace std;
 
int main()
{
    const int N=3;
    int A[N][N];
    srand(time(NULL));
 
    for (int i=0;i<N;i++)
        for (int j=0;j<N;j++)
            A[i][j]=rand()%10-10;       
        for (int i=0;i<N;i++){
            for (int j=0;j<N;j++){
                cout<<A[i][j]<<"  ";}
            cout<<endl;}
 
}
Сам удивился.

UPS. Сорри, const то я и не заметил
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
13.06.2014, 11:14     Выделение динамической памяти #17
Цитата Сообщение от Faoxis Посмотреть сообщение
Вот задача полностью (Delphi я не знаю):
В первом варианте это оказался обычный массив с предельной размерностью. А во втором уже линейный список.

Добавлено через 55 секунд
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
C++
1
const int N=3; int A[N][N];
Это не VLA. Это обычный массив, размер которого известен на момент компиляции, т.к. N константа.
Faoxis
6 / 6 / 0
Регистрация: 11.04.2012
Сообщений: 114
13.06.2014, 11:20  [ТС]     Выделение динамической памяти #18
Цитата Сообщение от Tulosba Посмотреть сообщение
А во втором уже линейный список.
А как его лучше реализовать ? Через какие операторы ?
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
13.06.2014, 11:23     Выделение динамической памяти #19
Faoxis, никаких особенных операторов не надо в первом приближении. Обычная реализация односвязного линейного списка. Об этом можно почитать в куче мест.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.06.2014, 11:35     Выделение динамической памяти
Еще ссылки по теме:

C++ Выделение динамической памяти
C++ Освобождение и выделение динамической памяти
Выделение динамической памяти C++

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

Или воспользуйтесь поиском по форуму:
Faoxis
6 / 6 / 0
Регистрация: 11.04.2012
Сообщений: 114
13.06.2014, 11:35  [ТС]     Выделение динамической памяти #20
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Пример взят с сайта [url]http://victor192007.narod.ru/files/cpp_d1.html[/url] и немного изменен для удобства
#include <iostream>
using namespace std;
 
//============================
 struct List
{
   int lst;
   List *next;
 
};
 
 //.............................................................
 int main()
 {
     List *var = NULL;
     var = new List; // А почему не указываем размер ? Например, как var = new List[size]
     var -> lst = 3; // Вот оператор "->". Пока не понятно, что происходит здесь
    var -> next = NULL; // и здесь
 
     return 0;
 }
Yandex
Объявления
13.06.2014, 11:35     Выделение динамической памяти
Ответ Создать тему
Опции темы

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