Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/22: Рейтинг темы: голосов - 22, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 04.09.2019
Сообщений: 15
1

Высвобождение памяти Free Си

12.11.2019, 21:29. Показов 4094. Ответов 15

Author24 — интернет-сервис помощи студентам
В общем столкнулся с такой проблемой не могу высвободить область выделенной памяти . Пожалуйста помогите, а то в притык не вижу как все исправить. P.s В отладчике останавливается на 59 сточке где высвобождаю выделенную память (цикла). Да и советы по динамической выделению памяти дайте.

Вот код:
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
#include<stdio.h>
#include<stdlib.h>
int **arr(int,int,int,int ***);
int main(void)
{
    //переменные для итерации
    int i,j,k=1,n,m;char sig;int **f = 0;
    do{
        printf("Enter elements [+|-] >");scanf("%s",&sig);printf("\n");
        switch(sig)
        {
            case '+':
                printf("Enter numbers n >");scanf("%d",&n);printf("\n");
                printf("Enter numbers m >");scanf("%d",&m);printf("\n");
                int **x = arr(n,m,k,&f);
                for(i=0;i<n;i++)
                {
                    for(j=0;j<m;j++)
                    {
                        printf("|%d",x[i][j]);
                    }
                    printf("\n");
                }
                k++;
                break;
            case '-':
                printf("exit\n");
                k=0;
                break;
            default:
                printf("Anew\n");
                k++;
                continue;
        }
 
    }while(k!=0);
}
int **arr(int n,int m,int k,int ***x)
{
   static int M=0;
   int i,j;
   switch(k)
   {
        case 1:
            *x = (int**)malloc(n*sizeof(int*));
            for(i=0;i<m;i++){
                (*x)[i] = (int*)malloc(m*sizeof(int));
            }
            for(i=0;i<n;i++)
            {
                for(j=0;j<m;j++)
                {
                    (*x)[i][j] = i+j;
                }
            }
            M=m;
            break;
        default:
            for(i=0;i<M;i++)free(x[i]);
            free(x);
            (*x) = NULL;
            //повторное выделение
            *x = (int**)malloc(n*sizeof(int*));
            for(i=0;i<m;i++){
                (*x)[i] = (int*)malloc(m*sizeof(int));
            }
            for(i=0;i<n;i++)
            {
                for(j=0;j<m;j++)
                {
                    (*x)[i][j] = 2+j;
                }
            }
            M=m;
 
   }
   return (*x);
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.11.2019, 21:29
Ответы с готовыми решениями:

Утечка памяти в free()
Приветствую. Стоит задача вывести заданное количество символов из последовательности Фибоначчи....

Корректная очистка памяти через Free
Доброго времени суток! Столкнулся со след. ситуацией. есть код: #include &lt;stdio.h&gt;...

Освобождение памяти - операцию free компилятор не пропускает
почему в этой функции операцию free компилятор не пропускает? int free_arr(int *arr, int count)...

Высвобождение памяти массивов
Доброго времени суток! Такой вопрос: Как освободить выделенную память под массивы arr1, arr2,...

15
Заблокирован
12.11.2019, 21:35 2
Жэсть какая - 100500 однобуквенных переменных и трёхмерные массивы.
Чо, хоть, прога делать-то должна?
--------
Лучше не отвечай, мне и так уже страшно.
Кликните здесь для просмотра всего текста


1
0 / 0 / 0
Регистрация: 04.09.2019
Сообщений: 15
12.11.2019, 22:23  [ТС] 3
Мнда... тут вроде не 200 строк кода что бы не разобраться лол. Тем более этот пример поможет мне доделать как раз таки прогу где 300 с лишним строк, но раз так не понятно ок.
1. Вызов функции где выделяется динамическая память
2. По оператору выбора (в зависимости от значения k ) будет выполнен определенный программный код case N:
3. Выполняем необходимые вычисления и записываем в память
4. После возвращаем указатель на выделенную область памяти
5. Идет вывод массива на экран
6. Меняем значение k для итерации
7. После идет вызываем повторно функцию где выполняется default
Там должен Удалятся исходные вычисленные значения в выделенной памяти.
Обнуляется x = NULL. И выделяется повторная память и также вычисляются новые значения для выделенной памяти
Вроде все подробно.

Добавлено через 4 минуты
Да можно было проще сделать, но вот интересно было усложнить запись двумерного массива.
0
Заблокирован
12.11.2019, 22:51 4
Цитата Сообщение от Falck Посмотреть сообщение
Мнда... тут вроде не 200 строк кода что бы не разобраться лол.
Достаточно. Пойду-ка я спать.
0
3881 / 2479 / 418
Регистрация: 09.09.2017
Сообщений: 10,884
13.11.2019, 09:50 5
Цитата Сообщение от Verevkin Посмотреть сообщение
и трёхмерные массивы
Не, массивы тут одномерные. Правда, ТС решил из них собрать указатель на массив массивов, что само по себе то еще извращение.
Цитата Сообщение от Falck Посмотреть сообщение
Мнда... тут вроде не 200 строк кода что бы не разобраться лол.
Вы не учитываете мотивацию. Тут народ сидит и помогает новичкам для удовольствия, из желания решить интересную задачу или предотвратить типичную ошибку.
Ковыряться даже в полусотне строк чужого кода, не имея представления что он должен делать, желающих мало.
Цитата Сообщение от Falck Посмотреть сообщение
Тем более этот пример поможет мне доделать как раз таки прогу где 300 с лишним строк
Вы же помните рекомендацию делить программу на модули (классы, функции и т.п.) по ~25 строк в каждой? Чтобы сразу было понятно для чего функция нужна и как ей пользоваться, чтобы ее можно было охватить взглядом.
Ну и однобуквенные переменные без комментариев - зло.
Цитата Сообщение от Falck Посмотреть сообщение
1.
2.
3.
4.
Вас спрашивали не как программа должна работать по вашему представлению, а что она должна делать в итоге. "Как" можно узнать и из кода, но раз вы пришли с вопросом на форум, в коде наверняка есть ошибки, то есть полагаться на его достоверность нельзя. Так откуда Verevkin'у знать что должна делать программа?
Цитата Сообщение от Falck Посмотреть сообщение
C
1
2
3
int **arr(int n,int m,int k,int ***x)
...
*x = (int**)malloc(n*sizeof(int*));
Вы передаете в функцию какой-то указатель, не проверяете его, не освобождаете, и тут же выделяете ему кусок памяти. Не знаю какое действие под этим задумывалось, но выглядит как архитектурный косяк.
То, что функция называется arr, а аргументы n, m, k, x без комментариев - не просто выглядит как косяк, а совершенно точно им является.
Цитата Сообщение от Falck Посмотреть сообщение
switch(k)
switch для двух вариантов? Довольно странное решение, если только не планируется расширение в дальнейшем.
Но даже в этом случае правильнее разделить функцию на несколько и вызывать по необходимости: одна функция - одна задача.
Цитата Сообщение от Falck Посмотреть сообщение
for(i=0;i<M;i++)free(x[i]);
Я, конечно, не разобрался до конца в этом ужасе, но разве не надо этот указатель сначала разыменовать, и только потом брать индекс? А то у вас указатель на массив массивов, а вы берете индекс от самого указателя, да еще его же и удаляете. В следующей строчке вообще удаляете ссылку на статическую переменную.
0
0 / 0 / 0
Регистрация: 04.09.2019
Сообщений: 15
13.11.2019, 13:36  [ТС] 6
COKPOWEHEU, Мне не стоило с психу отправлять подобный кусок херни. И написать грамотно что и к чему. Да и спасибо насчет критики.
Посмотрите пожалуйста вот этот вариант когда там с присущими комментариями все расписано.
Програмка должна выводить двумерный массив при этом под двумерный массив выделяется память в функции void arr(void)

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
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
void arr(int,int);//функция где выделяется динамическая память 
int main(void)
{
    //переменные для итерации
    int k=1,n,m;//k используется в цикле и пока k = 1 он будет бесконечен 
                //n - строки в двумерном массиве; m - колличесво элементов в одной строке 
    char sig;// используется в операторе выбора - в зависимости от символа записаном по адресу 
            // будет выполнятся определенный кейс 
    do{
        printf("Enter elements [+|-] >");scanf("%s",&sig);printf("\n");
        switch(sig)
        {
            case '+':
                printf("Enter the number of rows n >");scanf("%d",&n);printf("\n");//вводим строки 
                printf("Enter the number of items m >");scanf("%d",&m);printf("\n");//вводим колличество элементов 
                arr(n,m);//вызов функции 
                break;
            case '-':
                printf("exit\n");//выход 
                k=0;
                break;
            default:
                printf("Anew\n");// выполняется если ввели некорретный символ 
                continue;
        }
 
    }while(k!=0);
}
void arr(int n,int m)
{
   int i,j;//переменные для индексации 
   //динамическое выделение памяти (n - строки под массив)
   int **x = (int**)malloc(n*sizeof(int*));
   //динамическое выделение пвамяти под (m - столбцы в массиве )
   for(i=0;i<m;i++){
        x[i] = (int*)malloc(m*sizeof(int));
   }
   
   for(i=0;i<n;i++)
    {
        for(j=0;j<m;j++)
        {
            x[i][j] = i+j-2;//делаем небольшие вычисления и записываем в выделенную память 
            printf("|%d",x[i][j]);//после выводим в консоль что получилось 
        }
            printf("|\n");
    }
    printf("\n");
    //высвобождение памяти которая была выделенна через цикл (колличесвто элементов в одной строке)
    for(i=0;i<m;i++){
        free(x[i]);
    }
    free(x);//высвобождение выделенной памяти для указателя (n - строк)
}
0
Эксперт CЭксперт С++
5113 / 4552 / 854
Регистрация: 07.10.2015
Сообщений: 9,462
13.11.2019, 13:58 7
Falck, чуток исправил, чуток подправил. Смотрите:
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<stdlib.h>
#include<conio.h>
 
void arr(int, int);//функция где выделяется динамическая память 
 
int main(void)
{
    //переменные для итерации
    int k = 1, n, m;//k используется в цикле и пока k = 1 он будет бесконечен 
                //n - строки в двумерном массиве; m - колличесво элементов в одной строке 
    char sig;// используется в операторе выбора - в зависимости от символа записаном по адресу 
            // будет выполнятся определенный кейс 
    do 
    {
        printf("Enter elements [+|-] > ");
        sig = _getch();
        
        switch (sig)
        {
            case '+':
                printf("+\nEnter the number of rows n > ");
                scanf("%d", &n);//вводим строки 
                
                printf("Enter the number of items m > ");
                scanf("%d", &m);//вводим колличество элементов 
                printf("\n");
                
                arr(n, m);//вызов функции 
                break;
            
            case '-':
                printf("-\nexit\n");//выход 
                k = 0;
                break;
            
            default:
                printf("Anew\n");// выполняется если ввели некорретный символ 
        }
 
    } while (k != 0);
}
void arr(int n, int m)
{
    int i, j;//переменные для индексации 
    //динамическое выделение памяти (n - строки под массив)
    int **x = (int**)malloc(n * sizeof(int*));
    //динамическое выделение пвамяти под (m - столбцы в массиве )
    for (i = 0;i < n;i++) 
        x[i] = (int*)malloc(m * sizeof(int));
 
    for (i = 0;i < n;i++)
    {
        for (j = 0;j < m;j++)
        {
            x[i][j] = i + j - 2;//делаем небольшие вычисления и записываем в выделенную память 
            printf("|%3d", x[i][j]);//после выводим в консоль что получилось 
        }
        printf("|\n");
    }
    printf("\n");
    //высвобождение памяти которая была выделенна через цикл (колличесвто элементов в одной строке)
    for (i = 0; i < n; i++) 
        free(x[i]);
    free(x);//высвобождение выделенной памяти для указателя (n - строк)
}
0
0 / 0 / 0
Регистрация: 04.09.2019
Сообщений: 15
13.11.2019, 14:16  [ТС] 8
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Не, массивы тут одномерные. Правда, ТС решил из них собрать указатель на массив массивов, что само по себе то еще извращение.

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

Вы же помните рекомендацию делить программу на модули (классы, функции и т.п.) по ~25 строк в каждой? Чтобы сразу было понятно для чего функция нужна и как ей пользоваться, чтобы ее можно было охватить взглядом.
Ну и однобуквенные переменные без комментариев - зло.

Вас спрашивали не как программа должна работать по вашему представлению, а что она должна делать в итоге. "Как" можно узнать и из кода, но раз вы пришли с вопросом на форум, в коде наверняка есть ошибки, то есть полагаться на его достоверность нельзя. Так откуда Verevkin'у знать что должна делать программа?

Вы передаете в функцию какой-то указатель, не проверяете его, не освобождаете, и тут же выделяете ему кусок памяти. Не знаю какое действие под этим задумывалось, но выглядит как архитектурный косяк.
То, что функция называется arr, а аргументы n, m, k, x без комментариев - не просто выглядит как косяк, а совершенно точно им является.

switch для двух вариантов? Довольно странное решение, если только не планируется расширение в дальнейшем.
Но даже в этом случае правильнее разделить функцию на несколько и вызывать по необходимости: одна функция - одна задача.

Я, конечно, не разобрался до конца в этом ужасе, но разве не надо этот указатель сначала разыменовать, и только потом брать индекс? А то у вас указатель на массив массивов, а вы берете индекс от самого указателя, да еще его же и удаляете. В следующей строчке вообще удаляете ссылку на статическую переменную.
COKPOWEHEU, Ааа то есть
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
указатель сначала разыменовать, и только потом брать индекс
это получается нужно с начало удалить выделенную память под указатели , а только после удалять выделенную память под количество элементов.

Добавлено через 16 минут
liv, Вот это я затупил,нужно было при выделение памяти для количество элементов в цикле поставить i < n
Цитата Сообщение от liv Посмотреть сообщение
//динамическое выделение пвамяти под (m - столбцы в массиве )
    for (i = 0;i < n;i++)
        x[i] = (int*)malloc(m * sizeof(int));
И да пару вопросов.
1. Если я высвобождаю выделенную память которая была выделена под указатель
Цитата Сообщение от liv Посмотреть сообщение
//динамическое выделение памяти (n - строки под массив)
    int **x = (int**)malloc(n * sizeof(int*));
...
free(x), а затем высвобождаю то что было выделено циклом будет ли это ошибкой или это практикуется.
2. По поводу архитектуры по коду > как было сказано выше ^ я так понимаю лучше иметь много функций которые решают каждый одну задачу чем много непонятного кода в двух или трех функциях ? Я правильно понимаю ?
0
Эксперт CЭксперт С++
5113 / 4552 / 854
Регистрация: 07.10.2015
Сообщений: 9,462
13.11.2019, 14:24 9
Falck, 1. Если сначала освободить память массива указателей, т.е. х, то его содержимое будет потеряно, поэтому осводить память под строки уже не получится.
2. Надо писать так, чтобы было понятно. Это главное. И да, разбивка на мелкие фрагменты, желательно с комментариями, в целом способствует тому, чтобы быстрее понять суть.

Добавлено через 1 минуту
Цитата Сообщение от Falck Посмотреть сообщение
нужно было при выделение памяти для количество элементов в цикле поставить i < n
При освобожении тоже
1
3881 / 2479 / 418
Регистрация: 09.09.2017
Сообщений: 10,884
13.11.2019, 14:46 10
Цитата Сообщение от Falck Посмотреть сообщение
printf("Enter elements [+|-] >");scanf("%s",&sig);printf("\n");
Это вы зря в одну строчку.
Функция scanf: вы ей передаете формат строки, но указатель на символ. Лучше воспользоваться форматом "%c" а еще лучше - getchar(), только будьте внимательнее с пробельными символами после предыдущих операций.
Цитата Сообщение от Falck Посмотреть сообщение
void arr(int n,int m)
Функция выделяет массив массивов, заполняет какими-то значениями, выводит их и освобождает память. Как-то непонятна цель всего этого. Ну и название как было "однобуквенным", так и осталось.
Цитата Сообщение от Falck Посмотреть сообщение
это получается нужно с начало удалить выделенную память под указатели , а только после удалять выделенную память под количество элементов.
Что такое "память под количество элементов"?
В функцию у вас передавался указатель на массив массивов. То есть при удалении нужно сначала удалить каждый из вложенных массивов, а потом "внешний" массив. Сам указатель трогать не надо, он вообще константа.
Код
int **arr(int n,int m,int k,int ***x)
(x)    - указатель на массив массивов (что-то, переданное снаружи по ссылке)
(*x)   - сам массив массивов (он же указатель на первый элемент "внешнего" массива)
(**x)  - элемент массива массивов ("внутренний" массив)
(***x) - элемент "внутреннего" массива, значение
Освобождать память от элемента "внутреннего" массива (***х) нельзя: он существует не сам по себе, а только в составе массива
Освобождать целиком память от "внутренних" и "внешнего" массива (**x и *x) надо - вы ее выделяли.
Освобождать память от указателя на массив массивов снова нельзя, поскольку это ссылка на статическую переменную, а памятью под них заведует компилятор, а не вы.
То есть освобождение этой штуки должно выглядеть как (АХТУНГ! писал на форуме, церебральный компилятор забагован)
C
1
2
3
4
void free_arr_of_arrs(int ***arr, int arr_size){
  for(int i=0; i<arr_size; i++) free( (*arr)[i] );
  free( *arr );
}
Цитата Сообщение от Falck Посмотреть сообщение
Посмотрите пожалуйста вот этот вариант когда там с присущими комментариями все расписано.
А вот решаемая задача все еще не расписана.
0
0 / 0 / 0
Регистрация: 04.09.2019
Сообщений: 15
13.11.2019, 16:30  [ТС] 11
COKPOWEHEU, Мнда ну и намутил я кашу ! Нужно выделять память точно не подобным образом но почему решил себе жизнь усложнить. Мол а может быть вот так тоже можно. Спасибо за выделенные ошибки. Совет такой дали использовал динамическую память высвободи память и также перед return!
0
Вездепух
Эксперт CЭксперт С++
11694 / 6373 / 1723
Регистрация: 18.10.2014
Сообщений: 16,059
13.11.2019, 22:58 12
Цитата Сообщение от Falck Посмотреть сообщение
Совет такой дали использовал динамическую память высвободи память и также перед return!
Этой грубейше неправильный и безграмотный анти-совет. Одна из главнейших причин использования динамическую памяти - именно возможность НЕ освобождать ее "перед return". Это ключевое свойство динамической памяти, ради которого ее и используют в подавляющем большинстве случаев.

Если время жизни вашей динамической памяти совпадает с временем жизни автоматических переменных (то есть вы ее освобождаете "перед return"), то во многих случаях это означает, что вам вообще не нужна была динамическая память.

Освобождать выделенную динамическую память, конечно, надо. Но правила "освобождай "перед return" не существует и никогда не существовало.
1
3881 / 2479 / 418
Регистрация: 09.09.2017
Сообщений: 10,884
14.11.2019, 10:07 13
Лучший ответ Сообщение было отмечено Falck как решение

Решение

Вот пример работы с двумерным массивом без 100500 однобуквенных переменных и с разделением выделения-освобождения памяти:
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
#include <stdio.h>
#include <stdlib.h>
 
//создание двумерного массива через отображение на одномерный
//и запонение его чем-то
int* create_arr(int w, int h){
  int *res = (int*)malloc(sizeof(int)*w*h);
  if(res == NULL)return NULL;
  for(int i=0; i<w; i++)
    for(int j=0; j<h; j++)
      if(i==j)res[i + j*w] = 1; else res[i + j*w] = 0; //знаю, можно было через memset сделать, но так адресация нагляднее
  return res;
}
 
//удаление массива
void free_arr(int *arr){
  free(arr);
}
 
//что-то делаем с массивом. Даже не важно что
void modify_arr(int *arr, int w, int h){
  for(int i=0; i<w; i++){
    arr[i + 0*w] = 5;
    arr[i + (h-1)*w] = 6;
  }
  for(int j=1; j<h; j++){
    arr[0 + j*w] = 7;
    arr[(w-1) + j*w] = 1;
  }
}
 
//отображение массива
void display_arr(int *arr, int w, int h){
  int idx = 0;
  for(int j=0; j<h; j++){
    for(int i=0; i<w; i++)printf("%i\t", arr[idx++]);
    printf("\n");
  }
}
 
int main(){
  int *arr, w, h;
  printf("Array size (WxH): ");
  scanf("%i%i", &w, &h);
  arr = create_arr(w, h);
#warning Не забываем проверку!
  if(arr == NULL){
    fprintf(stderr, "Can not allocate %i bytes!\n", sizeof(int)*w*h);
    return -1;
  }
  
  //что-то с ним делаем
  display_arr(arr, w, h);
  printf("---\n");
  modify_arr(arr, w, h);
  arr[1 + w*2] = 10;
  display_arr(arr, w, h);
  
  free_arr(arr); //когда надоело возиться с массивом - удаляем
}
1
0 / 0 / 0
Регистрация: 04.09.2019
Сообщений: 15
14.11.2019, 13:42  [ТС] 14
COKPOWEHEU, достаточно интересно, но вот некоторые операции мне непонятны.

Добавлено через 14 минут
COKPOWEHEU, Расскажите пожалуйста что проверяет
1. 11 строка и зачем нужны эти операции в индексе массива
2.для чего арифметические операциии в индексе массива 23,24,27,28 строке
3.56 строка тот же вопрос что и выше
0
Эксперт CЭксперт С++
5113 / 4552 / 854
Регистрация: 07.10.2015
Сообщений: 9,462
14.11.2019, 13:57 15
Falck, это элементарно, Ватсон
Это работа с матрицей, как с одномерным массивом.
Длина строки (количество столбцов) = w
Значит, индекс 0-го элемента очередной строки = w * i, где i - индекс этой строки
Добавив индекс столбца j, получим индекс элемента [i, j]
1
3881 / 2479 / 418
Регистрация: 09.09.2017
Сообщений: 10,884
14.11.2019, 14:00 16
Нарисуем массив в виде массива:
Код
a11  a21  a31 ... aW1
a12  a22  a32 ... aW2
a13  a23  a33 ... aW3
...  ...  ...  .  ...
a1H  a2H  a3H ... aWH
А теперь развернем в линию, то есть расположим строки не одну над другой, а просто последовательно:
Код
(a11  a21  a31 ... aW1) (a12  a22  a32 ... aW2) (a13  a23  a33 ... aW3) ... (a1H  a2H  a3H ... aWH)
Поскольку длина каждой строки W, то 0-я строка занимает индексы от 0 до (W-1), первая строка от W до (W+W-1), вторая от (W+W до W+W+W-1), и так далее. Если записать в общем виде, j-я строка занимает индексы от (j*W) до (j*W+W-1).
Ну а навигация внутри строки как была линейной, так и осталась, то есть i-й элемент любой строки будет отстоять на i индексов от ее начала. Скажем, третий элемент 0-й строки займет место 3, третий элемент 1-й строки (3+W), третий элемент 2-й строки (3+2*W) и так далее.
Ну и в общем виде линейный индекс элемента [i, j] превращается в [i + W*j].
Самое замечательное, что такое представление прекрасно масштабируется на массивы любой размерности. Скажем, для 4-мерного массива элемент [i,j,k,l] будет выглядеть как [i + j*W + k*W*H + l*W*H*D].
При том, что для машины это все еще единый непрерывный кусок памяти, то есть не нужно никаких тонн выделений - освобождений. Ну и групповые операции - тоже приятный бонус: всякие memcpy, memcmp, memset и т.п.
1
14.11.2019, 14:00
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.11.2019, 14:00
Помогаю со студенческими работами здесь

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

Высвобождение динамической памяти
Нужна помощь, в проблеме высвобождения памяти, все делаю по стандартам С++, но постоянно выдает...

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

Высвобождение памяти статического массива
Возник такой вопрос - память из под статических массивов высвобождается автоматически? То-есть...


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

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