Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.06.2013, 15:55   #1
Че Гевара
Форумчанин
 
Аватар для Че Гевара
 
Регистрация: 25.09.2012
Сообщений: 182
По умолчанию Динамическое выделение памяти под матрицу. Не понимаю как работает.

В книжке был вот такой пример
Код:
typedef int *pInt; // новый тип данных: указатель на целое
main()
{
int M, N, i;
pInt *A; // указатель на указатель
// ввод M и N
A = new pInt[M]; // выделить память под массив указателей
for ( i = 0; i < M; i ++ ) // цикл по всем указателям
A[i] = new int[N]; // выделяем память на строку i
// работаем с матрицей A, как обычно
for ( i = 0; i < M; i ++ ) // освобождаем память для всех строк
delete A[i];
delete A; // освобождаем массив указателей
}
Однако мне не очень понравилось то, что в нём используется typedef. Немного поэксперементировав я получил следующий код, который вполне работает
Код:
//////////////////////////////////////////////////////////////////////
/*Динамическое выделение памяти под матрицу (при помощи средств C++)*/
//////////////////////////////////////////////////////////////////////

#include <conio.h>
#include <stdio.h>
#include <locale.h>

main()
{
setlocale(LC_ALL,"RUS");
int i, j, M, N;
int **A;
scanf("%d%d",&M,&N);
A = new (int*);
	if(A == NULL)
	{
	printf("Ошибка при выделении памяти ");
	getch();
	return 1;
	}
	for(i = 0;i < M;i++)
	{
	A[i] = new int[N];
		if(A[i] == NULL) 
		{
		printf("Ошибка при выделении памяти");
		getch();
		return 1;
		}
	}
	for(i = 0;i < M;i++)
	{
		for(j = 0;j < N;j++) printf("%10d ",A[i][j]);
	printf("\n");
	}
	for(i = 0;i < M;i++) delete A[i];
delete A;
getch();   
}
Вот только я не совсем теперь понимаю как и почему он работает, а именно эта строка
Код:
A = new (int*);
В оригинале в этом месте в указатель на указатель на целое число записывается адрес первого элемента массива указателей на целое число. Что в него записывается теперь и какого размера получается массив указателей? Объясните пожалуйста.
Отладка кода вдвое сложнее, чем его написание. Так что если вы пишете код настолько умно, насколько можете, то вы по определению недостаточно сообразительны, чтобы его отлаживать.
Brian W. Kernighan.

Последний раз редактировалось Че Гевара; 03.06.2013 в 16:17.
Че Гевара вне форума Ответить с цитированием
Старый 03.06.2013, 17:04   #2
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

Программа "работает", но правильно ли?
По-моему, A = new (int*); выделит память под ОДИН элемент типа "указатель на int". Дальнейший код "лезет" в память, ему не принадлежащую.
Нужно:
Код:
A = new int*[M];
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 03.06.2013, 17:20   #3
Bugrimov
C/C++, Java
Участник клуба
 
Аватар для Bugrimov
 
Регистрация: 28.03.2012
Сообщений: 1,680
По умолчанию

Согласен с BDA. Когда вы пишете
Код:
A = new (int*);
выделяется 4 Б. Если есть желание можно проверить
Код:
sizeof(A)
. А вам нужно М указателей насколько я понял. Отсюда и
Код:
A = new int*[M];

А то что не забыли delete - похвально.... Бывает об этом моменте забывают.
"Keep it simple" - придерживайтесь простоты!
Уильям Оккам - "Не следует множить сущее без необходимости"
Сложность - враг простоты и удобства!

Последний раз редактировалось Bugrimov; 03.06.2013 в 17:42.
Bugrimov вне форума Ответить с цитированием
Старый 03.06.2013, 17:27   #4
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

Bugrimov, придется с Вами не согласиться в некоторых моментах.
A = new (int*); - выделяется 4 байта (зависит от компилятора)
sizeof(A) - вернет размер указателя указателя на инт, т.е. 4
sizeof не вернет размер динамического массива
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 03.06.2013, 17:30   #5
Че Гевара
Форумчанин
 
Аватар для Че Гевара
 
Регистрация: 25.09.2012
Сообщений: 182
По умолчанию

Странно, работает корректно, хотя сам уже понимаю, что лезу в чужую память, однако программа не падает.
Снимок.jpg
Впрочем свою ошибку уже понял, действительно нужно
Код:
A = new int*[M];
Всем спасибо
Отладка кода вдвое сложнее, чем его написание. Так что если вы пишете код настолько умно, насколько можете, то вы по определению недостаточно сообразительны, чтобы его отлаживать.
Brian W. Kernighan.
Че Гевара вне форума Ответить с цитированием
Старый 03.06.2013, 17:34   #6
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

http://stackoverflow.com/questions/1...s-no-error-why
Цитата:
Сообщение от stackoverflow
Welcome to every C/C++ programmers bestest friend: Undefined Behavior.

There is a lot that is not specified by the language standard, for a variety of reasons. This is one of them.

In general, whenever you encounter undefined behavior, anything might happen. The application may crash, it may freeze, it may eject your CD-ROM drive or make demons come out of your nose.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 03.06.2013, 17:41   #7
Bugrimov
C/C++, Java
Участник клуба
 
Аватар для Bugrimov
 
Регистрация: 28.03.2012
Сообщений: 1,680
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Bugrimov, придется с Вами не согласиться в некоторых моментах.
A = new (int*); - выделяется 4 байта (зависит от компилятора)
sizeof(A) - вернет размер указателя указателя на инт, т.е. 4
sizeof не вернет размер динамического массива
Насчет того что это зависит от компилятора - возможно, хотя объем типа я так думал что зависит от архитектуры системы. А про размер динамического массива вообще не шла речь. Естественно sizeof вернет в данном случае 4 байта, размер одного указателя на int.
"Keep it simple" - придерживайтесь простоты!
Уильям Оккам - "Не следует множить сущее без необходимости"
Сложность - враг простоты и удобства!
Bugrimov вне форума Ответить с цитированием
Старый 03.06.2013, 17:43   #8
Че Гевара
Форумчанин
 
Аватар для Че Гевара
 
Регистрация: 25.09.2012
Сообщений: 182
По умолчанию

Цитата:
Сообщение от stackoverflow
Welcome to every C/C++ programmers bestest friend: Undefined Behavior.

There is a lot that is not specified by the language standard, for a variety of reasons. This is one of them.

In general, whenever you encounter undefined behavior, anything might happen. The application may crash, it may freeze, it may eject your CD-ROM drive or make demons come out of your nose.
Демоны из носа это жёстко...Нам такого счастья не надо
Отладка кода вдвое сложнее, чем его написание. Так что если вы пишете код настолько умно, насколько можете, то вы по определению недостаточно сообразительны, чтобы его отлаживать.
Brian W. Kernighan.
Че Гевара вне форума Ответить с цитированием
Старый 03.06.2013, 17:48   #9
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

Цитата:
Сообщение от Bugrimov Посмотреть сообщение
А про размер динамического массива вообще не шла речь. Естественно sizeof вернет в данном случае 4 байта, размер одного указателя на int.
Я Вас не так понял в этом моменте.
Цитата:
Сообщение от Че Гевара Посмотреть сообщение
Демоны из носа это жёстко...Нам такого счастья не надо
Ага, там были и более интересные примеры далее, но не стал их цитировать, а то мало ли
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Язык СИ! Динамическое выделение памяти под массивы и матрицы, передача матрицы в функции Андрей! Общие вопросы C/C++ 33 31.01.2012 22:07
Динамическое выделение памяти, как лучше? Пепел Феникса Общие вопросы по программированию, компьютерный форум 10 11.03.2010 09:44
Динамическое выделение памяти под массив объектов со специализированным конструктором capta1n Общие вопросы C/C++ 6 07.03.2010 16:01
динамическое выделение памяти под верхний треугольник квадратной матрицы juventine Помощь студентам 2 12.04.2009 13:02
Динамическое выделение памяти под массивы Артем125 Общие вопросы C/C++ 4 07.04.2009 09:52