Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
Lifeda92
0 / 0 / 0
Регистрация: 26.08.2014
Сообщений: 14
1

Malloc (выделение памяти двумерному массиву) - проверить код

26.08.2014, 13:55. Просмотров 919. Ответов 5
Метки нет (Все метки)

Здравствуйте, подскажите пожалуйста, есть ли логические ошибки в блоке "Выделения памяти:"?

План по выделению памяти:
1. Выделяется массив указателей с кол-во элементов n (0..n-1).
2. Выделяется двумерный массив с кол-во элементов n*n (n..2n-1, 2n..3n-1, 3n..4n-1, 4n..5n-1).
3. Указатели массива указателей, указывают на адреса ячеек двумерного массива с интервалами n..2n-1, 2n..3n-1, 3n..4n-1, 4n..5n-1.

Программа делает то что я думаю?
Спасибо.

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
/* malloc.cpp */
 
#include <stdlib.h> // Местонахождение фн-ции "void *malloc(size_t size);"
#include <stdio.h> // Местонахождение фн-ции "int printf(const char *управляющая_строка, ...);"
 
typedef unsigned int un_int; // Новое имя целочисленного неотрицательного типа
static const un_int n = 4; // Указывает ШхД двумерного массива
 
int main() {
//-----------------> Выделение памяти:
 
    int **m = (int**)malloc(n*sizeof(int*) + sizeof(int)*n*n); // Выделяем память массиву указателей |*|*|*|*| + двумерному массиву |&|&|&|&|
    for (un_int i = n-1, k = 1; i+1 < n+n; ++i, ++k)
        m[i+1-n] = (int*)&m[i+1*k]; // Передаем адрес ячейки указателю с интервалом "i+1*k"
    
//-----------------> Заполнение массива числами от 0..(n*n-1):
 
    for (un_int i = 0, k = 0; i < n; ++i) {
                for (un_int j = 0; j < n; ++j, ++k)
                        m[i][j] = k;
        }
 
//-----------------> Вывод содержимого массива на консоль (терминал):
 
        for (un_int i = 0; i < n; ++i) {
                for (un_int j = 0; j < n; ++j)
                        printf("%d ", m[i][j]);
        printf("\n");
        }
 
//-----------------> Освобождение памяти:
 
    free(m);
 
//-----------------> Возврат 0 значения фн-ции main():
 
    return 0;
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.08.2014, 13:55
Ответы с готовыми решениями:

Динамическое выделение памяти, нужен ли <malloc.h>?
если используешь функцию malloc, обязательно перед этим подключать соответствующую библиотеку...

Выделение памяти под структуры (malloc)
Доброго времени суток! Нужна помощь в выделении памяти для структуры с указателями. Можете...

Компилятор ругается на выделение памяти malloc
#include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;string.h&gt; #include &lt;locale.h&gt; /* СТУДЕНТ: ...

Выделение памяти массиву структур в функции
Добрый день. Программа работает с записями, в виде массива структур: #define STRLENGTH 20 ...

Задача по двумерному массиву
Создать матрицу B из целых чисел. Из каждой строки напечатать числа, которых нет в следующей...

5
Kuzia domovenok
2550 / 2229 / 558
Регистрация: 25.03.2012
Сообщений: 8,072
Записей в блоге: 1
Завершенные тесты: 1
26.08.2014, 14:20 2
Цитата Сообщение от Lifeda92 Посмотреть сообщение
C++
1
int **m = (int**)malloc(n*sizeof(int*) + sizeof(int)*n*n); // Выделяем память массиву указателей |*|*|*|*| + двумерному массиву |&|&|&|&| for (un_int i = n-1, k = 1; i+1 < n+n; ++i, ++k) m[i+1-n] = (int*)&m[i+1*k]; // Передаем адрес ячейки указателю с интервалом "i+1*k"
какой-то дикий бред... я просто понять не могу, что тут происходит!?
для начала ответь, что такое n*sizeof(int*) + sizeof(int)*n*n ?

Добавлено через 6 минут
Цитата Сообщение от Lifeda92 Посмотреть сообщение
m[i+1-n] = (int*)&m[i+1*k];
вот это точно неправильно. i+1*k это i+k
1
Lifeda92
0 / 0 / 0
Регистрация: 26.08.2014
Сообщений: 14
26.08.2014, 14:52  [ТС] 3
i+1*k тут да, завтыкал=) хотел написать (i+1)*k или n*k

int **m = (int**)malloc(n*sizeof(int*) + sizeof(int)*n*n); <-- Тут я создаю массив указателей и еще просто 1 длинный массив.

Добавлено через 6 минут
Я хотел чтобы было вот так:

|*| -> |&|&|&|&|
0 ----- 4 5 6 7

|*| -> |&|&|&|&|
1 ----- 8 9 10 11

|*| -> |&|&|&|&|
2 ----- 12 13 14 15

|*| -> |&|&|&|&|
3 ----- 16 17 18 19
0
Lifeda92
0 / 0 / 0
Регистрация: 26.08.2014
Сообщений: 14
28.08.2014, 00:57  [ТС] 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
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
/* malloc.cpp */ // Имя файла
 
#include <stdlib.h> // Местонахождение фн-ции "void *malloc(size_t size);"
#include <stdio.h> // Местонахождение фн-ции "int printf(const char *управляющая_строка, ...);"
#include <iostream> // Местонахождение классов, фн-ций и переменных для организации ввода-вывода.
 
using namespace std; // открыть пространство имен библ. iostream
 
typedef unsigned int un_int; // Новое имя целочисленного неотрицательного типа
static const un_int len = 4, wid = 2; // Указывает ДxШ двумерного массива
static const int diff = wid - len; // Разница
 
void mem_test(int** &m) { // ----------> Фн-ция проверки указателей, которые указывают по нужным адресам до и после присвоения указателям нужных адресов (резул. выводится на консоль (терминал))
 
    for (un_int i = 0, j = wid - diff; i < len; ++i) {
        //printf("%d  ----->  ", *(&m[i]));
        cout << *(&m[i]) << "  ----->  ";
 
        for (un_int k = 0; k < wid; ++k, ++j) {
            switch (j) {
            case wid - diff:
                //printf("%d ", &m[len]);
                cout << &m[len] << " ";
                break;
 
            default:
                //printf("%d ", &m[j]);
                cout << &m[j] << " ";
            }
        }
 
        printf("\n");
    }
 
    printf("\n");
}
 
int main() {
//-----------------> Выделение памяти:
 
    int **m = (int**)malloc(len*sizeof(int*)+sizeof(int)*len*wid); // Тут я создаю массив указателей (n), и еще просто 1 длинный массив (n*n) в котором будут храниться целые числа
 
    mem_test(m);
 
    for (un_int i = len - 1, k = 1; i < len + len - 1; ++i, ++k)
        switch (i) {
        case len - 1:
            m[0] = (int*)&m[len];
            break;
 
        default:
            m[i + 1 - len] = (int*)&m[wid*k - diff];
        }
 
    mem_test(m);
 
/*
------------------------------------------------------------------
 
    Схемы (n=4):
 
------------------------------------------------------------------
 
    int **m = (int**)malloc(n*sizeof(int*) + sizeof(int)*n*n);
 
    |*|*|*|*|&|&|&|&|&|&|&|&|&|&|&|&|&|&|&|&|
 
------------------------------------------------------------------
 
    for (un_int i = n-1, k = 1; i+1 < n+n; ++i, ++k)
        m[i+1-n] = (int*)&m[n*k];
 
    |*| -> |&|&|&|&|
    0 ----- 4 5 6 7
 
    |*| -> |&|&|&|&|
    1 ----- 8 9 10 11
 
    |*| -> |&|&|&|&|
    2 ----- 12 13 14 15
 
    |*| -> |&|&|&|&|
    3 ----- 16 17 18 19
 
------------------------------------------------------------------
*/
 
//-----------------> Заполнение массива числами от 0..(wid*len-1):
 
    for (un_int i = 0, k = 0; i < len; ++i) {
        for (un_int j = 0; j < wid; ++j, ++k) {
            m[i][j] = k;
            //printf("%d ", &m[i][j]);
            cout << &m[i][j] << " ";
        }
 
        printf("\n");
    }
 
    printf("\n");
 
//-----------------> Вывод содержимого массива на консоль (терминал):
 
    for (un_int i = 0; i < len; ++i) {
        for (un_int j = 0; j < wid; ++j)
            printf("%d ", m[i][j]);
    printf("\n");
    }
            
//-----------------> Освобождение памяти:
 
    free(m);
 
//-----------------> Возврат 0 значения фн-ции main():
 
    return 0;
}
На выходе получил:

Код
Это до указания указателям на нужные адреса:

0x93939393  ----->  0x9387448 0x938744c 
0x93939393  ----->  0x9387450 0x9387454 
0x93939393  ----->  0x9387458 0x938745c 
0x93939393  ----->  0x9387460 0x9387464 

Это после указания указателям на нужные адреса:

0x9387448  ----->  0x9387448 0x938744c 
0x9387450  ----->  0x9387450 0x9387454 
0x9387458  ----->  0x9387458 0x938745c 
0x9387460  ----->  0x9387460 0x9387464 

Это те адреса по которым находятся числовые значения:

0x9387448 0x938744c 
0x9387450 0x9387454 
0x9387458 0x938745c 
0x9387460 0x9387464 

Это числовые значения по адресам выше:

0 1 
2 3 
4 5 
6 7
Подскажите пожалуйста, доказывает ли этот тест, что память выделяется правильно, и все указатели указывают туда куда надо.

(Или я что-то не то начудил И совсем не так все понимаю... )

Спасибо.
0
easybudda
Модератор
Эксперт JavaЭксперт CЭксперт С++
10297 / 6179 / 1555
Регистрация: 25.07.2009
Сообщений: 11,762
29.08.2014, 00:04 5
Lifeda92, крайне неудачная затея - смешивать в одной программе С и С++, особенно, когда речь о динамической памяти. Если пишите на С++, используйте new[] / delete[]
1
Lifeda92
0 / 0 / 0
Регистрация: 26.08.2014
Сообщений: 14
29.08.2014, 12:35  [ТС] 6
Та да, что то, я какую-то кашу малашу написал.
Спасибо за совет.
0
29.08.2014, 12:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.08.2014, 12:35

Двумерному массиву присвоить одномерный
Здравствуйте! По ходу считывания из файла строка помещается в одномерный массив buffer: while...

Ошибка при обращении к двумерному массиву char, размещенному в стеке, из другой функции
int main() { char s = { &quot;test1\0&quot;, &quot;test2\0&quot; }; foo(s); } void foo(char** array) {...

Выделение памяти malloc
не работает пример из лекции , там пример на доске такой написан - #include &lt;stdlib.h&gt; int...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru