Ru-MaNGOS

Вернуться   Ru-MaNGOS > Документация > Новичкам

Важная информация

Новичкам Информация для всех новичков, новичкам рекомендуется задавать свои вопросы здесь

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 26.12.2012, 13:01   #1
lovepsone
Ученый
 
Регистрация: 07.03.2010
Адрес: Беларусь,Брест
Сообщений: 188
Сказал(а) спасибо: 131
Поблагодарили 34 раз(а) в 27 сообщениях
lovepsone Хрен знает что...lovepsone Хрен знает что...
По умолчанию Динамические массивы в С++

Нужна помощь и пояснения!
Вот мой говнокод:
Код:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <ctime> // для time
#include <cstdlib> // для srand

int main()
{
	//std::srand(static_cast<unsigned int>(std::time(0)));
	setlocale(LC_ALL, "rus");
	int m,n;
	printf("Введите размерность массива:\n"
			"Кол-во строк = ");

	std::scanf("%d",&n);
	printf("Кол-во столбцов = ");
	std::scanf("%d",&m);

	int** mas = new int*[n];

	for (int i = 0; i < m; i++)
		mas[i] = new int[m];

	for (int i = 0; i < n; i++)
	{
		for(int j = 0; j < m; j++)
			mas[i,j] = (int*)(40 - (std::rand() % 31));
	}

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
			printf("%d ", mas[i,j]);
		printf("\n");
	}

	for (int i = 0; i < m; i++)
		delete mas[i]; // вот тут ошибка
	delete [] mas;

	system("pause");
	return 0;
}
При освобождении памяти происходит ошибка!
Компилю в 10 визуалке;
__________________
sql-language.ru

Последний раз редактировалось lovepsone; 26.12.2012 в 16:33.
lovepsone вне форума   Ответить с цитированием
Старый 26.12.2012, 16:03   #2
Vladimir
MaNGOS Dev
 
Регистрация: 09.02.2010
Сообщений: 594
Сказал(а) спасибо: 315
Поблагодарили 438 раз(а) в 181 сообщениях
Vladimir Как свет с небесVladimir Как свет с небесVladimir Как свет с небесVladimir Как свет с небесVladimir Как свет с небесVladimir Как свет с небес
По умолчанию

Код:
for (int i = 0; i < m; i++)
delete mas[i]; // вот тут ошибка
почему m если при создании
int** mas = new int*[n];
__________________
Так как устал объяснять знайте ICQ не пользуюсь
Vladimir вне форума   Ответить с цитированием
Старый 26.12.2012, 16:24   #3
lovepsone
Ученый
 
Регистрация: 07.03.2010
Адрес: Беларусь,Брест
Сообщений: 188
Сказал(а) спасибо: 131
Поблагодарили 34 раз(а) в 27 сообщениях
lovepsone Хрен знает что...lovepsone Хрен знает что...
По умолчанию

Цитата:
Сообщение от Vladimir Посмотреть сообщение
Код:
for (int i = 0; i < m; i++)
delete mas[i]; // вот тут ошибка
почему m если при создании
int** mas = new int*[n];
Вроде мы сразу освобождаем колонки (чтобы освободить память необходимо выполнить цикл для освобождения одномерных массивов), а потом строки. Или нет?
Даже если заменить на переменную n, все ровно происходит ошибка кучи, типо куча повреждена!

И еще вопрос: как заполнить матрицу, что бы строки не повторялись? Я попробовал использовать srand(), но толку ноль!
__________________
sql-language.ru

Последний раз редактировалось lovepsone; 26.12.2012 в 16:35.
lovepsone вне форума   Ответить с цитированием
Старый 28.12.2012, 12:41   #4
Йоха
Умный
 
Регистрация: 02.07.2010
Сообщений: 434
Сказал(а) спасибо: 27
Поблагодарили 73 раз(а) в 45 сообщениях
Йоха Скоро придёт к известности
По умолчанию

В современном состоянии языка с++ использовать в прикладных целях голые указатели - моветон!

В данном случае нужно использовать std::vector

Твою программу можно переписать например так:
Код:
#include <conio.h>
#include <iostream>
#include <iomanip>
#include <vector>

int _tmain(int argc, _TCHAR* argv[])
{
	std::vector<std::vector<int>> mas;
	int n, m;
	std::cout << "Enter array size - n m : " << std::endl;
	std::cin >> n >> m;

	srand((unsigned int)time(NULL));
	for (int i = 0; i < n; i++) {
		std::vector<int> tmp;
		for(int j = 0; j < m; j++)
			tmp.push_back(40 - rand() % 31);
		mas.push_back(tmp);
	}

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++)
			std::cout << std::setw(4) << mas[i][j];
		std::cout << std::endl;
	}

	_getch();
	return 0;
}
Или такой вариант заполнения матрицы без использования временных переменных:
Код:
	srand((unsigned int)time(NULL));
	mas.resize(n);
	for (int i = 0; i < n; i++) {
		mas[i].resize(m);
		for (int j = 0; j < m; j++)
			mas[i][j] = 40 - rand() % 31;
	}
А по поводу твоей программы - это просто тихий ужас!

Ошибка №1
Код:
int** mas = new int*[n];
for (int i = 0; i < m; i++)
mas[i] = new int[m];
У тебя выделен массив длиной n, а заполняешь его ты в цикле по m !

Ошибка №2
Код:
mas[i,j] = (int*)(40 - (std::rand() % 31));
Обращение к двумерным массивам в с++ пишеттся как mas[i][j].
То что написал ты - это вызов оператора запятая.
Собственно этот код эквивалентен следующему:
Код:
mas[j] = (int*)(40 - (std::rand() % 31));
Потом, тут само присвоение неправильно, ты на место указателя записываешь число.

Ошибка №3
Код:
for (int i = 0; i < m; i++)
delete mas[i]; // вот тут ошибка
Ты выделял память под массив, а удаляешь как одну переменную.
Надо писать delete[] mas[i];
Ну и как уже заметили, цикл идет по m, хотя массив длиной n.

Ну с учетом всех косяком, исправил твою прогу:
Код:
int main()
{
	srand((unsigned int)(time(NULL)));
	setlocale(LC_ALL, "rus");
	int m,n;
	printf("Введите размерность массива:\nКол-во строк = ");
	scanf_s("%d",&n);
	printf("Кол-во столбцов = ");
	scanf_s("%d",&m);

	int** mas = new int*[n];
	for (int i = 0; i < n; i++)
		mas[i] = new int[m];

	for (int i = 0; i < n; i++)
		for(int j = 0; j < m; j++)
			mas[i][j] = 40 - rand() % 31;

	for (int i = 0; i < n; i++) {
		for(int j = 0; j < m; j++)
			printf("%d ", mas[i][j]);
		printf("\n");
	}

	for (int i = 0; i < n; i++)
		delete[] mas[i];
	delete[] mas;
	return 0;
}
Все работает как и ожидается.

И напоследок, у тебя в программе смесь языков С и С++, все этим пережитки прошлого в виде printf и scanf... У С++ есть iostream для ввода вывода

Последний раз редактировалось Йоха; 28.12.2012 в 14:27.
Йоха вне форума   Ответить с цитированием
Старый 28.12.2012, 18:42   #5
lovepsone
Ученый
 
Регистрация: 07.03.2010
Адрес: Беларусь,Брест
Сообщений: 188
Сказал(а) спасибо: 131
Поблагодарили 34 раз(а) в 27 сообщениях
lovepsone Хрен знает что...lovepsone Хрен знает что...
По умолчанию

Спасибо за все. В моем случаи использовать вектор не надо.
Цитата:
Сообщение от Йоха Посмотреть сообщение
И напоследок, у тебя в программе смесь языков С и С++, все этим пережитки прошлого в виде printf и scanf... У С++ есть iostream для ввода вывода
Вы имеете ввиду std::cin и std::cout? В ошибке №2 описался и не заметил(просто скомпилилось)...
Разберу код который вы написали и все осмыслю...

П.С.
Я тока изучаю с++
__________________
sql-language.ru

Последний раз редактировалось lovepsone; 28.12.2012 в 18:46.
lovepsone вне форума   Ответить с цитированием
Старый 29.12.2012, 08:25   #6
Йоха
Умный
 
Регистрация: 02.07.2010
Сообщений: 434
Сказал(а) спасибо: 27
Поблагодарили 73 раз(а) в 45 сообщениях
Йоха Скоро придёт к известности
По умолчанию

Цитата:
Сообщение от lovepsone Посмотреть сообщение
В моем случаи использовать вектор не надо.
Это обязательное условие задачи - не использовать vector ? Если так то ок, иначе настоятельно рекомендую не использовать new и delete, для указателей - смарт поинтеры, для динамических массивов vector или подобное (list, deque ... в зависимости от условий задачи)

Цитата:
Сообщение от lovepsone Посмотреть сообщение
В ошибке №2 описался и не заметил(просто скомпилилось)...
К несчастью в с++ полно возможностей описаться, при этом с точки зрения компилятора код будет корректным, но работать это все будет совсем не так как задумывалось.

Кстати еще насчет динамических массивов: двумерный массив размерностью m на n можно создать так :
Код:
int *mas = new int[m * n];
и дальше использовать как обычно:
Код:
mas[i][j] = 1;
Йоха вне форума   Ответить с цитированием
Старый 29.12.2012, 10:07   #7
lovepsone
Ученый
 
Регистрация: 07.03.2010
Адрес: Беларусь,Брест
Сообщений: 188
Сказал(а) спасибо: 131
Поблагодарили 34 раз(а) в 27 сообщениях
lovepsone Хрен знает что...lovepsone Хрен знает что...
По умолчанию

Цитата:
Сообщение от Йоха Посмотреть сообщение
Кстати еще насчет динамических массивов: двумерный массив размерностью m на n можно создать так :
Код:
int *mas = new int[m * n];
и дальше использовать как обычно:
Код:
mas[i][j] = 1;
Попробуем использовать....
__________________
sql-language.ru
lovepsone вне форума   Ответить с цитированием
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.



Текущее время: 12:40. Часовой пояс GMT +3.


ru-mangos.ru - Русское сообщество MaNGOS
Главная цель проекта MaNGOS - обучающая, поэтому разрешается использовать исходный код и собранную программу только для образовательных целей.
Вы не можете использовать MaNGOS в коммерческих целях, а также не разрешается устанавливать публичные серверы на базе MaNGOS.
Любое копирование материалов, информации в любом виде без указания источника - форума Ru-MaNGOS будет считаться нарушением авторских прав и нарушением Уголовного Кодекса РФ, ст. 146 ст. 147.
Перевод vBulletin: zCarot