Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.60/43: Рейтинг темы: голосов - 43, средняя оценка - 4.60
7 / 7 / 0
Регистрация: 25.09.2010
Сообщений: 31
1

Перераспределение динамической памяти

12.11.2010, 12:13. Показов 8557. Ответов 21
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
дан двумерный массив 3х5 выделить динамически память под него, затем перераспределить ее в массив 5х3, затем удалить(выделить и удалить там все понятно, помогите найти ошибку в перераспределении)
C++
1
2
3
4
5
6
int**a=(*int)calloc(3,sizeff(*int));
         for(int i=0; i<3; i++)
             a[i]=(*int)calloc(5,sizeof(int));
         realloc(a, 5*sizeof(int*));
         for(int i=0; i<5; i++)
             realloc(a[i], 4*sizeof(int));
1
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.11.2010, 12:13
Ответы с готовыми решениями:

Перераспределение динамической памяти
дан двумерный массив 3х5 выделить динамически память под него, затем перераспределить ее в массив...

Перераспределение памяти
int Add(datas value, int position) { _count++; node = (DoubleList*)realloc(node,...

Перераспределение памяти
ifstream&amp; operator&gt;&gt; (ifstream&amp; in, Toy&amp; ob) { size_t len; in.read((char*)&amp;len, sizeof(len));...

Перераспределение памяти с new под объекты
есть класс #include &lt;iostream&gt; #include &lt;string&gt; using namespace std; class tel_book {...

21
246 / 178 / 47
Регистрация: 14.06.2010
Сообщений: 422
12.11.2010, 12:35 2
что значит sizeff???????
0
7 / 7 / 0
Регистрация: 25.09.2010
Сообщений: 31
12.11.2010, 16:58  [ТС] 3
Цитата Сообщение от TheMachinist Посмотреть сообщение
что значит sizeff???????
опечатка
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,680
12.11.2010, 18:42 4
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
#include <stdlib.h>
int main () {
 
 
 //Коль скоротреба перераспределять память, то думаем.т Массива 3 на 5 это 15 ячеек памяти. Массив 5 на 3
 //это тоже 15 ячеек. Для полного счастья на не хватает, чтобы эти 15 ячеек были не разбросаны, как попало
 //в памяти, а шли подряд
 
 //Поэтому выделяем их
 int* p= new int [15];
 
 //Теперь занимаемся массивом  3 на 5
 int**a=(int**)calloc(3,sizeof(int*));
 for(int i=0; i<3; i++) 
  a[i]= &p[i* 5];
 
 //Всё, теперь эти 15 ячеек массив 3 на 5 (3 строки по 5 столбцов)
 
 //А перераспределяем так:
 int**b=(int**)calloc(5,sizeof(int*));
 for(int i=0; i<5; i++) 
  b[i]= &p[i* 3];
 
 
 //Ну и удаляем потом память
 delete [] p;
 free (b);
 free (a);
 
 
 return 0;
                         
}
1
Day
1180 / 990 / 83
Регистрация: 29.10.2009
Сообщений: 1,385
12.11.2010, 20:18 5
Цитата Сообщение от Rikimaru Посмотреть сообщение
дан двумерный массив 3х5 выделить динамически память под него, затем перераспределить ее в массив 5х3, затем удалить(выделить и удалить там все понятно, помогите найти ошибку в перераспределении)
C++
1
2
3
4
5
6
int**a=(*int)calloc(3,sizeff(*int));
         for(int i=0; i<3; i++)
             a[i]=(*int)calloc(5,sizeof(int));
         realloc(a, 5*sizeof(int*));
         for(int i=0; i<5; i++)
             realloc(a[i], 4*sizeof(int));
Вот здесь for(int i=0; i<5; i++) realloc(a[i], 4*sizeof(int));при i>2 реаллокачивать нечего,
a[i] просто неизвестно кто, и при i>2 надо делать calloc

Добавлено через 1 минуту
И еще.
Надо
C
1
 a[i] = realloc(a[i], ....);
2
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
13.11.2010, 01:50 6
Цитата Сообщение от Day Посмотреть сообщение
И еще.
Надо
C
1
 a[i] = realloc(a[i], ....);
нужен промежуточный указатель, realloc() может вернуть NULL

Цитата Сообщение от Rikimaru
дан двумерный массив 3х5 выделить динамически память под него, затем перераспределить ее в массив 5х3
перевыделять нужно a, a[0], a[1], a[2] и довыделять a[3], a[4]
2
62 / 62 / 13
Регистрация: 27.01.2009
Сообщений: 279
14.11.2010, 13:09 7
Цитата Сообщение от Rikimaru Посмотреть сообщение
дан двумерный массив 3х5 выделить динамически память под него, затем перераспределить ее в массив 5х3, затем удалить(выделить и удалить там все понятно, помогите найти ошибку в перераспределении)
C++
1
2
3
4
5
6
int**a=(*int)calloc(3,sizeff(*int));
         for(int i=0; i<3; i++)
             a[i]=(*int)calloc(5,sizeof(int));
         realloc(a, 5*sizeof(int*));
         for(int i=0; i<5; i++)
             realloc(a[i], 4*sizeof(int));
C
1
2
3
4
5
6
7
8
9
// Allocating memory
int**a=(**int) calloc(3, sizeof(int*));
for(int i = 0; i < 3; ++i)
    a[i]=(*int) calloc(5, sizeof(int));
 
// Re-allocating memory
a = (int**) realloc((int *) a, 5 * sizeof(int*));
for(int i = 0; i < 5; ++i)
    a[i]=calloc(3, sizeof(int));
Освободить думаю сможешь сам
Есть вопросы задавай
2
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
14.11.2010, 22:49 8
C
1
a = (int**) realloc((int *) a, 5 * sizeof(int*));
нельзя так делать, нужен промежуточный указатель

смотри, в a был указатель на память, ты начал выделять realloc'ом новый кусок побольше и памяти не хватило, realloc возвращает NULL и что ?
в а записывается NULL, а куда делся кусок, который там был ?
потерлся - утечка памяти
2
62 / 62 / 13
Регистрация: 27.01.2009
Сообщений: 279
15.11.2010, 00:28 9
Цитата Сообщение от accept Посмотреть сообщение
нельзя так делать, нужен промежуточный указатель
то есть вот так?
C
1
2
3
4
5
6
7
8
9
10
// Allocating memory
int**a=(**int) calloc(3, sizeof(int*));
for(int i = 0; i < 3; ++i)
    a[i]=(*int) calloc(5, sizeof(int));
 
// Re-allocating memory
int **b = (int**) realloc((int *) a, 5 * sizeof(int*));
if (!b) // освобождаем память по указателю a и завершаем программу с ошибкой
for(int i = 0; i < 5; ++i)
    b[i]=calloc(3, sizeof(int));
Еще возник вопрос если я выделяю выше описанным образов, то есть сначала выделяю память для массива с 3 указателей, потом в значение этого указателя записываю поочередно указатель на массив который состоит с 5 значений
Вопрос - куда деваются адреса после вызова realloc, я сделал вывод адресов до и после realloc'а результаты разные для верхнего массива?
надеюсь ясно выразился...
2
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
15.11.2010, 02:14 10
Лучший ответ Сообщение было отмечено как решение

Решение

если b == NULL, то мы ничего не делаем, а если b != NULL, то мы делаем a[i] = b
можно из цикла выйти, можно вывести сообщение и программу завершить, главное нельзя сразу в a[i] записывать, а то потеряются данные, которые там были до этого (если перевыделение памяти не состоится) и сам указатель на ту память, которая там была, тоже

Добавлено через 4 минуты
Цитата Сообщение от norge_goth
Вопрос - куда деваются адреса после вызова realloc
C89
Код
4.10.3.4 The realloc function

Synopsis

         #include <stdlib.h>
         void *realloc(void *ptr, size_t size);

Description

   The realloc function changes the size of the object pointed to by
ptr to the size specified by size .  The contents of the object shall
be unchanged up to the lesser of the new and old sizes.  If the new
size is larger, the value of the newly allocated portion of the object
is indeterminate.  If ptr is a null pointer, the realloc function
behaves like the malloc function for the specified size.  Otherwise,
if ptr does not match a pointer earlier returned by the calloc ,
malloc , or realloc function, or if the space has been deallocated by
a call to the free or realloc function, the behavior is undefined.  If
the space cannot be allocated, the object pointed to by ptr is
unchanged.  If size is zero and ptr is not a null pointer, the object
it points to is freed.

Returns

   The realloc function returns either a null pointer or a pointer to
the possibly moved allocated space.
понял да, possibly moved

Добавлено через 5 минут
знаешь, там еще реаллочить нужно строки (те, которые были), уменьшая до длины три
а новые строки просто выделить с длиной три, и всего две штуки
3
62 / 62 / 13
Регистрация: 27.01.2009
Сообщений: 279
16.11.2010, 12:05 11
Цитата Сообщение от accept Посмотреть сообщение
знаешь, там еще реаллочить нужно строки (те, которые были), уменьшая до длины три
а новые строки просто выделить с длиной три, и всего две штуки
кажись сделано перераспределение и обработка всех последствий
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
#include <stdio.h>
#include <stdlib.h>
 
void freeAfter(int *ptr, int k);
 
int main(void)
{
    const int m = 3, n = 5;
    int **vect;
    int **a;
 
    // Allocating memory for m * n
    if (!(vect = (int** ) malloc(m * sizeof(int*))))
        exit(1);
 
    for (int i = 0; i < m; ++i)
        if(!(vect[i] = (int *) malloc(n * sizeof(int))))
        {
            free((int* )vect);
            exit(1);
        }
 
    // Reallocating memory for n * m
    if (!(a = (int** ) realloc((int* )vect, n * sizeof(int*))))
    {
        // Delete Allocated memory
        freeAfter((int* )vect, m);
        free((int* )vect);
        exit(1);
    }
 
    vect = a;
 
    for (int i = 0; i < m; ++i)
        if(!(vect[i] = (int *) realloc(vect[i], m * sizeof(int))))
        {
            freeAfter((int* )vect, m);
            free((int* )vect);
            exit(1);
        }
 
    for(int i = m; i < n; ++i)
        if(!(vect[i] = (int *) malloc(m * sizeof(int))))
        {
            freeAfter((int* )vect, m);
            free((int* )vect);
            exit(1);
        }
 
    // Delete Allocated memory
    for (int i = 0; i < n; ++i)
        free(vect[i]);
    free((int* )vect);
 
    printf("\n");
    system("PAUSE");
    return 0;
 
}
 
void freeAfter(int *ptr, int k)
{
    for (int i = 0; i < k; ++i)
        free((void* )ptr[i]);
}
2
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
16.11.2010, 13:41 12
Лучший ответ Сообщение было отмечено как решение

Решение

C
1
if (!(a = (int** ) realloc((int* )vect, n * sizeof(int*))))
vect - указатель второго порядка
вообще не надо приводить
C
1
if (!(a = (int** ) realloc(vect, n * sizeof(int*))))
C
1
free(vect);
приведение будет выполнено автоматически (аргументы функции приводятся к тем типам, которые указаны в прототипе функции)

C
1
if(!(vect[i] = (int *) realloc(vect[i], m * sizeof(int))))
здесь промежуточного указателя нет, в принципе тут выход из программы
но вот когда выход из программы не делается, необходим промежуточный указатель, чтобы указатель на старую память сохранить в случае NULL
3
62 / 62 / 13
Регистрация: 27.01.2009
Сообщений: 279
16.11.2010, 21:18 13
Цитата Сообщение от accept Посмотреть сообщение
здесь промежуточного указателя нет, в принципе тут выход из программы
но вот когда выход из программы не делается, необходим промежуточный указатель, чтобы указатель на старую память сохранить в случае NULL
еще такой вопрос - если мы сразу выходим с программы можно не освобождать память занятую ранее другим процессом? то есть код
C
1
2
3
4
5
6
7
for(int i = m; i < n; ++i)
        if(!(vect[i] = (int *) malloc(m * sizeof(int))))
        {
            freeAfter((int* )vect, m);
            free((int* )vect);
            exit(1);
        }
а записать просто:
C
1
2
3
for(int i = m; i < n; ++i)
        if(!(vect[i] = (int *) malloc(m * sizeof(int))))
              exit(1);
1
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,680
16.11.2010, 22:02 14
Осторожнее с терминами. Другой процесс- это другой процесс, в твоей программе создаётся только один процесс. Если он заканчивается, вся выделенная память возвращается оси.
Здесь читаем
По завершении процесса его код и выделенные ему ресурсы удаляются из памяти.
2
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
16.11.2010, 22:03 15
вообще принято освобождать, так как программа может стать частью другой программы

kravam, там же только про уиндоус
2
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,680
16.11.2010, 22:35 16
Навскидку если, я очень сильно сомневаюсь, что в линуксе оперативная память, отданная процессу по его окончании не будет возвращена оси БЕЗУСЛОВНО.

Второй раз вынужден попроситьбыть точнее с терминами. Что значит "программа может стать частью другой программы"? Если имеется ввиду отношение отец- сын, то все процессы, включая заявленный по определению чьи-то дети, либо проводника либо cmd (это в общем случае) или хитрого автроского процесса (это в частности). Автоматическое освобождение памяти (по убиению процесса) не повлияет ни на работу ни отцов ни детей ни стороннних прог, если конечно последние не используют диверсантский приём типа "запись в адресное пространство стороннего процесса"

Но в этом случае как показывает практика они НИЧЕГО не смогут туда записать (у меня, например, не срабатывает api-функция VirtualProtectEx). Следовательно, память действительно возвращается оси независимо от того, сколько прог её используют.
...А так-то конечно, лучше принудительно возвращать память оси
2
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
17.11.2010, 05:10 17
Цитата Сообщение от kravam
Что значит "программа может стать частью другой программы"?
это значит, что она может стать подпрограммой какой-нибудь программы и поэтому нужно её делать завершённой изначально
1
62 / 62 / 13
Регистрация: 27.01.2009
Сообщений: 279
20.11.2010, 22:20 18
Цитата Сообщение от kravam Посмотреть сообщение
Осторожнее с терминами. Другой процесс- это другой процесс, в твоей программе создаётся только один процесс. Если он заканчивается, вся выделенная память возвращается оси.
Здесь читаем
По завершении процесса его код и выделенные ему ресурсы удаляются из памяти.
почитал я эту информацию, возник вопрос так если мы создаем внутри одного процесса несколько потоков(трэдов) получается тоже что и при создании дочерных процессов(я имею ввиду распаралеливание выполнения программы)?
1
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,680
20.11.2010, 22:38 19
Нет. Ну тут много различий.

Вот одно из них, важное. Каждый поток должен иметь хотя бы ОДИН процесс. Если не будет ни одного потока, процесс убиется.

А теперь попробуем провести аналогию с дочерними процессами-, нет, не то же самое. Если исчезнут все дочерние процессы, отцовский процесс как работал так и будет работать.

(Кстати, верно и обратное. Если ты убьёшь процесс, это автоматом означает убиение всх потоков этого процесса. Но убитие процесса отнюдь не означает убитие всех его дочерних процессов)

А вообще это всё там расписано. Попробуй побольше почитать.

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

Вот псевдокод:
funktsia_1;
funktsia_2;
funktsia_3;

А если ты вместо них оеперь напишешь потоки, то они быдут выполняться ОДНОВРЕМЕННО. Ну, как одновременно-то один, то второй, то третий. Это уж как система распределит между ними время

potok_1;
potok_2;
potok_3;

Но, по-моему можно так под написать, что второй поток не выполнится, пока не закончится первый. Но это уже частный случай. А в общем если брать, то они будут выполняться ПСЕВДООДНОВРЕМЕННО. Вот в этом их отличие от функций. Ну и другие ещё наверное есть
1
62 / 62 / 13
Регистрация: 27.01.2009
Сообщений: 279
20.11.2010, 22:44 20
Цитата Сообщение от kravam Посмотреть сообщение
(Кстати, верно и обратное. Если ты убьёшь процесс, это автоматом означает убиение всх потоков этого процесса. Но убитие процесса отнюдь не означает убитие всех его дочерних процессов)
понятно, но я не то имел ввиду...
там сказано что ядро выделяет квантованное время для потока, то есть если мы будем иметь 1 процесс состоящий с двух потоков, а с другой стороны родительский процесс с дочерным процессом, которые имеют по одному потоку - в итоге и там и там будет отведено по 2 кванта процессорного времени(в сумме)?
1
20.11.2010, 22:44
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.11.2010, 22:44
Помогаю со студенческими работами здесь

std::vector Перераспределение памяти
Код #include &lt;iostream&gt; #include &lt;vector&gt; #include &lt;tchar.h&gt;...

Перераспределение памяти для стека
Помогите решить задачку, реализовал стек, осталось решить задачку.. Задача состоит в следующем:...

STL, deque Перераспределение памяти
Есть книга, в ней написано такое о деке Можно ли пример увидеть, а-то чего-то непонятно....

С помощью чего можно представить динамический массив, чтобы исключить перераспределение памяти?
С помощью чего можно представить динамический массив? Пробовал vector, но там перераспределение...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru