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

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

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

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

16.04.2010, 19:26. Просмотров 24813. Ответов 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!
1
Лучшие ответы (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
toxa92
167 / 94 / 2
Регистрация: 16.04.2010
Сообщений: 464
16.04.2010, 19:32 #2
надо выделить сначала массив указателей, а потом к каждому указателю прилепить по массиву чисел
2
neske
1502 / 869 / 84
Регистрация: 26.03.2010
Сообщений: 2,982
16.04.2010, 19:35  [ТС] #3
Спасибо, можно листинг?
0
MikeSoft
Эксперт С++
3801 / 1777 / 85
Регистрация: 21.11.2009
Сообщений: 2,540
16.04.2010, 19:37 #4
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
neske,

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int x,y;
//----------------------------------------------------------------------------
std::cout << "Введите кол-во строк в массиве: ";
std::cin >> x;
std::cout << "Введите кол-во столбцов в массиве: ";
std::cin >> y;
//------------------------Выделение памяти------------------------------------
int **mas = new int *[x];
 
for (int i = 0; i < x; i++) {
  mas[i] = new int [y];
}
//----------------------------------------------------------------------------
//                      Выполняйте действия, которые вам необходимы
//--------------------------Освобождение памяти----------------------------
for (int i = 0; i < x; i++) {
  delete []mas[i];
}
delete []mas;
8
neske
1502 / 869 / 84
Регистрация: 26.03.2010
Сообщений: 2,982
16.04.2010, 19:40  [ТС] #5
Проверил, работает, спасибо.
0
msangel
0 / 0 / 0
Регистрация: 10.03.2010
Сообщений: 13
04.05.2010, 07:21 #6
у меня встречный вопрос, чтоб уже добить эту тему:
освобождение правильное освобождение памяти:

у вашем примере вы освобождаете память с помощью такой конструкции:
C++
1
2
3
4
5
6
7
//----------------------------------------------------------------------------
//                      Выполняйте действия, которые вам необходимы
//--------------------------Освобождение памяти----------------------------
for (int i = 0; i < x; i++) {
  delete []mas[i];
}
delete []mas;
однако в учебнику пишут, что "Осводождение памяти из-под массива с любым количеством измерений с помощью операции delete[]"
Тоесть не надо делать то, что вы писали а достаточно только написать вот так:
C++
1
delete []mas;
???
0
easybudda
Модератор
Эксперт CЭксперт С++
9681 / 5631 / 954
Регистрация: 25.07.2009
Сообщений: 10,808
04.05.2010, 09:14 #7
msangel, странный учебник. MiCr0s0fT правильно написал - по сути каждый элемент массива mas сам по себе является указателем на массив. И память для каждого из них была выделена оператором new[], соответственно должна быть возвращена оператором delete[]. Я в нескольких умных книжках читал, что возвращать нужно ровно столько памяти, сколько брал. И как-то такой подход кажется более правильным, чем упование на то, что для каждого элемента массива указателей mas сам собой оператор delete[] будет вызван, а не просто потеряется указатель на выделенную память. Кстати, а что за учебник?
1
msangel
0 / 0 / 0
Регистрация: 10.03.2010
Сообщений: 13
04.05.2010, 09:30 #8
что за учебник не скажу .

но в продолжение темы:
возвращать нужно ровно столько памяти, сколько брать
как узнать, сколько памяти используется, кому она пренадлежит(стеку, метому, глобальной области) во время разработки программы?

как узнать, что происходит утечка памяти?
0
MikeSoft
Эксперт С++
3801 / 1777 / 85
Регистрация: 21.11.2009
Сообщений: 2,540
04.05.2010, 10:18 #9
msangel, easybudda, а я бы тоже не прочь узнать, что за учебник такой, кто так людей учит ... (судя по всему, обучалка для какой-нибудь современной IDE, где пользователь уже забыл, что значит "освободить память" - всё сделает машина)

И ещё интересно... а про обнуление в этом учебнике ничего не сказано?

Архангельский и Либерти, например, рекомендуют после высвобождения памяти производить обнуление значений. То есть, для примера:
C++
1
2
3
4
int *mas = new int [10];
// операции над массивом
delete []mas;
mas = NULL;
И вот что меня в этом удивило... Работаю в RAD Studio 2010.
У неё есть механизм анализа кода, который предупреждает, например, о том, что переменная была обьявлена, но нигде не использовалась...

Так вот, начинаю разработку проекта. Режим Debug.
Выделил память, попользовался ею, очистил. Обнулил. Компильнул - всё идеально.

Переключаюсь на Release.
Компилирую тот же код и получаю Warning'и в местах обнуления.
Предупреждение о том, что переменная больше нигде не используется.

Вот такие вот интересности из учебников...
0
easybudda
Модератор
Эксперт CЭксперт С++
9681 / 5631 / 954
Регистрация: 25.07.2009
Сообщений: 10,808
04.05.2010, 11:16 #10
Цитата Сообщение от MiCr0s0fT Посмотреть сообщение
Архангельский и Либерти, например, рекомендуют после высвобождения памяти производить обнуление значений.
Ну в принципе-то правильно рекомендуют. Суть в том, что если в программе после того, как память была возвращена оператором delete / free и значение указателя установлено в NULL, пытаясь по ошибке использовать тот же указатель программа грохнется с исключением типа "NULL pointer bla bla bla...". А вот если указатель не был установлен в NULL, программа будет пытаться использовать уже не инициализированный участок памяти, и вот тут поведение её не предсказуемо. Так, что, это просто мера предосторожности такая, но вполне разумная...
0
MikeSoft
Эксперт С++
3801 / 1777 / 85
Регистрация: 21.11.2009
Сообщений: 2,540
04.05.2010, 23:54 #11
easybudda, да, о мере предохранении от AV я осведомлён. Мне интересен сам факт, почему компилятор предупреждает о повторном использовании только что высвобожденного куска памяти. Не верится мне, что разработчики не учли случай "аккуратного" повторного использования того же участка памяти. (и именно в Release варианте сборки)
Возможно, существует какой-то другой рациональный метод ...
В данном случае мною движет чисто профессиональный интерес.
Завтра посмотрю, что скажет по этому поводу Visual Studio...
0
msangel
0 / 0 / 0
Регистрация: 10.03.2010
Сообщений: 13
05.05.2010, 00:35 #12
Не верится мне, что разработчики не учли случай "аккуратного" повторного использования того же участка памяти
у меня лично в 2008 студии возможно изменять и считывать переменные по адресу уже освобожденной памяти. разве память после удаления не перестает быть доступной?
а если остается доступной, то толку от этой чистки?

или может это потому, что оператор [] обеспечивает лиш доступ по смещению памяти и никаких проверок на доступность памяти не делает(в случае недоступности должна возбуздается ошыбка)
но ее нет и все работает
приведеный ниже код:

C++
1
2
3
4
    int *matr2 = new int [10];
    delete []matr2;
    matr2[15]=26;
    printf("%d",matr2[15]);
дает результат:
Код
26
Ни тут тебе проверок на доступность, ни на размер масива....
Почему так?
0
easybudda
Модератор
Эксперт CЭксперт С++
9681 / 5631 / 954
Регистрация: 25.07.2009
Сообщений: 10,808
05.05.2010, 00:47 #13
MiCr0s0fT, я думаю - всё проще. При релизной сборке какой-нибудь варн-левел повышается, и компилятор отслеживает случаи, когда после последнего изменения значения переменной она нигде больше не используется. Наверное, это одно из множества параноидальных предупреждений, на которые можно просто внимание не обращать. Ну или отключить, чтоб граза не мозолило...
Вот к примеру код
C
1
2
3
4
5
6
7
#include <stdio.h>
 
int main(void){
    int i = 5;
    printf("Hello, world!\n");
    return 0;
}
а вот, что мелкомягкий cl пишет, если параметр Wall (включить все предупреждения) задать
Выделение динамической памяти для двумерного массива.
На собственные заголовочные файлы ругается. Что ж теперь, stdio.h "испралять"?
0
easybudda
Модератор
Эксперт CЭксперт С++
9681 / 5631 / 954
Регистрация: 25.07.2009
Сообщений: 10,808
05.05.2010, 00:51 #14
msangel, попробуйте после
C++
1
delete []matr2;
добавить
C++
1
matr2 = NULL;
0
msangel
0 / 0 / 0
Регистрация: 10.03.2010
Сообщений: 13
05.05.2010, 01:07 #15
Цитата Сообщение от easybudda Посмотреть сообщение
msangel, попробуйте после
C++
1
delete []matr2;
добавить
C++
1
matr2 = NULL;
да, как я уже писал
оператор [] обеспечивает лиш доступ по смещению памят
поэтому естественно если нулевой адерес не может быть доступным, то и смещение невозможно отсчитать.
но вопрос как раз не в том.
вопрос состоит так:
должна возбуздается ошыбка
Ни тут тебе проверок на доступность, ни на размер масива
и все работает
разве память после удаления не перестает быть доступной?
0
05.05.2010, 01:07
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.05.2010, 01:07
Привет! Вот еще темы с ответами:

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

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

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

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


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

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

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