Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 179, средняя оценка - 4.82
neske
1505 / 872 / 84
Регистрация: 26.03.2010
Сообщений: 2,986
#1

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

16.04.2010, 19:26. Просмотров 25677. Ответов 23
Метки нет (Все метки)

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
#include <iostream>
 
int main()
{
    setlocale( LC_ALL,"Russian" );
 
    int N, M;
    std::cout << "Введите кол-во строк в массиве: ";
    std::cin >> N;
    std::cout << "Введите кол-во столбцов в массиве: ";
    std::cin >> M;
    int *MAS=new int [N][M];
 
    std::cout << "Первоначальный массив: " << std::endl;
    for (int i=0; i<N; i++) // заполняем массив с клавиатуры.
    for (int j=0; j<M; j++)
    {
        std::cout << "Массив["<<  i <<"]["<< j <<"]: ";
        std::cin >> MAS[i][j];
    }
    
    delete []MAS;
    system("pause");
    return 0;
}
Ошибка 1 error C2540: неконстантное выражение используется в качестве границы массива c:\visual studio 2008\projects\project1\example\example\kod.cpp
Ошибка 1 error C2540: неконстантное выражение используется в качестве границы массива c:\visual studio 2008\projects\project1\example\example\kod.cpp
Ошибка 3 error C2109: для индекса требуется массив или указатель c:\visual studio 2008\projects\project1\example\example\kod.cpp 20
Need help!
2
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.04.2010, 19:26
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Выделение динамической памяти для двумерного массива. (C++):

Выделение динамической памяти для массива точек - C++
Доброго времени суток. Вот у нас есть структура точка struct point { double x,y; } p;

Правильное выдиление динамической памяти для двумерного массива - C++
#include'iostream.h' #include'stdio.h' #include'string.h' void main() { char **text; int i,j,k,nm; char s; ...

Динамическое выделение памяти для двумерного массива - C++
нужна помощь вот тело программы, не могу сделать динамическое выделение памяти для первого двумерного массива. второй массив получается...

Как правильно записать в виде функции выделение памяти для двумерного массива и ее освобождение - C++
Здравствуйте! Подскажите, как правильно записать в виде функции выделение памяти для двумерного массива и ее освобождение. ...

Выделение динамической памяти для матрицы - C++
Здравствуйте! Подскажите, пожалуйста, что делаю не так..написала программу, которая считывает двумерный массив...с помощью операторов...

Выделение динамической памяти для char - C++
Здравствуйте, возник вопрос: как выделить память для char массива? Вот, что делаю я: #include &quot;stdafx.h&quot; #include&lt;iostream&gt; ...

23
mirso
525 / 343 / 17
Регистрация: 05.04.2009
Сообщений: 709
05.05.2010, 02:19 #16
msangel,
Цитата Сообщение от msangel Посмотреть сообщение
delete []matr2;
* * * * matr2[15]=26;
Еще прикольный вариант [-15]
C++
1
2
3
4
5
    int *matr2 = new int [1];
    delete []matr2;
    //matr2 = NULL;
    matr2[-15]=26;
    printf("%d\n",matr2[-15]);
Цитата Сообщение от msangel Посмотреть сообщение
Ни тут тебе проверок на доступность, ни на размер масива
0
msangel
0 / 0 / 0
Регистрация: 10.03.2010
Сообщений: 13
05.05.2010, 05:37 #17
да, это как минимум странно

я решил посмотреть как в таких случаях меняются адреса
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
    int *matr2 = new int [10];
    delete []matr2;
    //matr2 = NULL;
    printf("%d\n",matr2);
    matr2[-1]=26;
    printf("%d\n",matr2[-1]);
    printf("%d\n",&matr2[-1]);
    matr2[-2]=26;
    printf("%d\n",matr2[-2]);
    printf("%d\n",&matr2[-2]);
    matr2[1]=26;
    printf("%d\n",matr2[1]);
    printf("%n",&matr2[1]);
в результате у меня вишло -
C
1
2
3
4
matr2 = 3435312//адрес 0-го елемента
&matr2[1] = 3435316//адрес [1] елемента, что как видим на 4 больше чем у [0] т.е. sizeof(int)
&matr2[-1] = 3435308//адрес [-1] елемента, что как видим на 4 менше чем у [0]
&matr2[-2] = 3435304// еще на 4 менше
возникает следующие вопросы:
получается я могу розмещать в памяти за нужным мне адресом нужные объекты, если придумаю способ их сериализации в память?
конешно, возможно такой способ выделения памяти опасен тем, что приложение может по моих адресах разместить свои даные... хотя я об етом ничего не знаю...
как приложение управляет своей памятью? наверное у каждого приложения во время роботы создается таблица, где оно хранит используемые адреса, чтоб при динамичесском выделении памяти просто не писать поверх и указывать на свободные участки? возможно даже функции malloc/free и операторы new/delete и соответственно работают с такой таблицей?
или это в конце концов просто баг компилятора?

Добавлено через 22 минуты
да, я был прав
http://www.parashift.com/c++-faq-lit....html#faq-38.8
там написано об том, как выделяется динамеческая память

как я и предполагал - объекты пишутся прамо в память по смещению относительно указателя
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 // Original code: Fred* p = new Fred[n];
 Fred* p = (Fred*) operator new[] (n * sizeof(Fred));
 size_t i;
 try {
   for (i = 0; i < n; ++i)
     new(p + i) Fred();           // Placement new
 }
 catch (...) {
   while (i-- != 0)
     (p + i)->~Fred();            // Explicit call to the destructor
   operator delete[] (p);
   throw;
 }
 arrayLengthAssociation.insert(p, n);
где p - собственно указатель и
for (i = 0; i < n; ++i)
new(p + i) Fred(); - запись одного елемента по смещению

но самое интерестное тут:
arrayLengthAssociation.insert(p, n);
в хелпе написано, что:
arrayLengthAssociation is the imaginary name of a hidden, global associative array that maps from void* to "size_t"
ну естественно тут непоказано алгоритмы для поиска свободного участка памяти через этот глобальный асоциативный масив, и установление указателя на эту область.

а в реализации все делается наоборот:
// Original code: delete[] p;
C++
1
2
3
4
size_t n = arrayLengthAssociation.lookup(p);
 while (n-- != 0)
   (p + n)->~Fred();
 operator delete[] (p);

гм) теперь все логично.
именно поэтому мы свободно можем писать в любую (свободную) точку памяти.
всем спасибо за помощь.

Добавлено через 14 минут
нет
ну естественно тут непоказано алгоритмы для поиска свободного участка памяти через этот глобальный асоциативный масив, и установление указателя на эту область.
arrayLengthAssociation наверное работает только с количествами.
следовательно должен быть еще что-то, но уже с адресами

Добавлено через 23 минуты
так же было б интерестно узнать, как виделяется память под одну переменную\\
наверно программа просит об этом операционную систему
однако что то не могу найти таких исходников\\

Добавлено через 24 минуты
оу, уже нашел)))
http://en.wikipedia.org/wiki/Memory_pool
в ссилках под статьей интерестный исходник

и наверное выделеная таким образом память плюсуется к памяти приложения, расшыряя его адресное пространство
за это наверное тоже отвечают функции malloc/free и операторы new/delete - кроме всего они еще при необходимости запрашуют еще блок памяти или освобождают его))))

жаль, что передо мной не стоит задача написать собственный менеджер памяти, тут есть поле для творчества
0
fasked
Эксперт С++
4951 / 2531 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
05.05.2010, 08:01 #18
Цитата Сообщение от msangel Посмотреть сообщение
а в реализации все делается наоборот:
// Original code: delete[] p;
перегруженный оператор delete[] не расскажет тебе, как работает классический delete[]
0
msangel
0 / 0 / 0
Регистрация: 10.03.2010
Сообщений: 13
05.05.2010, 12:20 #19
перегруженный оператор delete[] не расскажет тебе, как работает классический delete[]
проблему собственно управлением памяти я затронул позже

тема же об
Выделение динамической памяти для двумерного массива.
и поетому я узнал, как работает удаление масива елементов
так как в даном примере в
C++
1
p
записан указатель на адрес начала масива объектов, то по сути по етому адресу записан масив указателей
поетому сначала удалаятся ппамять из под объектов, на которые ссылаются указатели:
C++
1
2
 while (n-- != 0)
   (p + n)->~Fred();
а уже потом собственно память из под самих указателей:
C++
1
operator delete[] (p);
я думаю, в реализации для одномернога масива базовых типов код выглядал бы так:
C++
1
2
3
size_t n = arrayLengthAssociation.lookup(p);
 while (n-- != 0)
   delete (p + n)
т.е. долхно выполнялоться как минимум 2 действия:
  • удаление информации о том, что память занимаема
  • собственно очистка памяти из под каждого элемента
0
mirso
525 / 343 / 17
Регистрация: 05.04.2009
Сообщений: 709
05.05.2010, 12:27 #20
Цитата Сообщение от mirso Посмотреть сообщение
Еще прикольный вариант [-15]
Код C++
* * int *matr2 = new int [1];
* * delete []matr2;
* * //matr2 = NULL;
* * matr2[-15]=26;
Цитата Сообщение от msangel Посмотреть сообщение
да, это как минимум странно
Цитата Сообщение от msangel Посмотреть сообщение
как в таких случаях меняются адреса
msangel, они там точно прикалывались -> &(i[matr2])
C++
1
2
3
    for(int i = -15; i <= 15; ++i)
    printf("%3d) %10d | %#10x | %u\n", i, i[matr2], &(i[matr2]),
                (&(i[matr2]) -  &((i - 1)[matr2]) )*sizeof(matr2));
0
MikeSoft
Эксперт С++
3802 / 1778 / 85
Регистрация: 21.11.2009
Сообщений: 2,540
05.05.2010, 13:16 #21
Цитата Сообщение от msangel Посмотреть сообщение
у меня лично в 2008 студии возможно изменять и считывать переменные по адресу уже освобожденной памяти. разве память после удаления не перестает быть доступной?
а если остается доступной, то толку от этой чистки?
Всё правильно. Вы же вызываете оператор new и просите его выделить память для хранения указанного типа, определённого размера. Вы всего лишь получаете указатель на выделенную память.

Цитата Сообщение от msangel Посмотреть сообщение
разве память после удаления не перестает быть доступной?
а если остается доступной, то толку от этой чистки?
В этом и беда. Очистили - память стала быть доступной. Но ведь у нас имеется указатель на этот участок. Поэтому, компилятор и не следит, как он дальше используется. С таким же успехом его мог переписать, например, другой поток программы. А удаление указателя - мера предосторожности, которая в дальнейшем и запретит возможность адресации к освобождённому участку.

А вот то, что нет проверок на то, какая область была выделена - это меня тоже добивает ...
И адресация в matr[-15] - тоже
0
challengerr
43 / 36 / 2
Регистрация: 30.07.2008
Сообщений: 136
30.09.2011, 13:17 #22
что неправильно?
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
#include <iostream>
using namespace std;
int **mas;
void func(int** mas, int x,int y)
{
int i,j;
mas = new int *[x];
for (i = 0; i < x; i++) {   mas[i] = new int [y];}
for (i = 0; i < x; i++) { for (j = 0; j < y; j++) { std::cin >> mas[i][j];}}
for (i = 0; i < x; i++) {for (j = 0; j < y; j++) {std::cout << mas[i][j];}std::cout << "\n";}
for (int i = 0; i < x; i++) {
  delete []mas[i];
}
delete []mas;
}
int main(int argc, char* argv[]) { 
int x,y,i,j;
//----------------------------------------------------------------------------
std::cout << "Введите кол-во строк в массиве: ";
std::cin >> x;
std::cout << "Введите кол-во столбцов в массиве: ";
std::cin >> y;
func(mas,x,y);
}
0
OstapBender
584 / 523 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
30.09.2011, 14:51 #23
всё правильно, но массив mas будет заполненым у вас только в функции func
1
KiSey
0 / 0 / 0
Регистрация: 13.05.2014
Сообщений: 1
16.05.2014, 12:12 #24
Вот еще вариант, здесь операция выделения динамической памяти выполняется 2 раза, разобраться как работает предлагаю особо любопытным))
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    int x;
    int y;
    cout << "Введите количество столбцов: ";
    cin >> x;    
    cout << "Введите количество строк: ";
    cin >> y;
    int *temp = new int [x*y];
    int **mas = new int *[y];
    for(int i = 0 ; i < y ; i++)
        mas[i]=&temp[i*x];
    //обращение аналогичное обычному двухмерному массиву:
    mas[3][2] = 10;
    cout << mas[3][2] << endl;
    //и освобождение памяти соответственно....
    delete []temp;
    delete []mas;
0
16.05.2014, 12:12
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.05.2014, 12:12
Привет! Вот еще темы с ответами:

Выделение динамической памяти для char[n]* - C++
Есть количество цитат (quote), которые должны быть типа char* Есть переменная с колличеством цитат (quoteNum) Вопрос: как выделить...

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

Выделение и удаление памяти, выделенной для динамической строки - C++
Данная функция производит ввод и собственно контроль ввода (размер массива от 1 до 20, иначе должна выдавать ошибку; при вводе букв также...

Выделение динамической памяти для чтения каждой структуры из файла - C++
Здравствуйте! Никак не получается выделить динамическую память под каждую структуру из файла, учитывая, что я не знаю сколько структур в...


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

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

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