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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 02.06.2018, 00:41   #1
c3nwen
 
Аватар для c3nwen
 
Регистрация: 01.06.2018
Сообщений: 9
Печаль Удаление двумерного массива из памяти

Друзья-товарищи, изучаю массивы. Ну и как бы все клево, но... Не дает спать мне один момент - освобождение памяти. Перепробовал уже хз все, что мог. Суть вопроса вот в чем, есть код:
Код:
#include <iostream>

using namespace std;
int rows = 0, cols = 0;
int **_array = new int*[rows];
void crt_array()
{
	for (int i = 0; i < rows; i++)
	{
		_array[i] = new int[cols];
		for (int j = 0; j < cols; j++) _array[i][j] = rand() % 400 + 100;
	}
}
void del_array()
{
	for (int i = 0; i < rows; i++) delete[] _array[i];
	delete[] _array;
}
void prt_array()
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++) cout << " " << _array[i][j];
		cout << endl;
	}
}
void main()
{
	setlocale(LC_ALL, "Russian");


	cout << "Введите количество Rows: "; cin >> rows;
	cout << "Введите количество Cols: "; cin >> cols;
	crt_array();
	prt_array();
	del_array();
	system("pause");
}
Ничего сверхъестественного, но при попытке освободить память, начинает дергаться вена на лбу. CRT обнаруживает, что приложение пытается что-то записать в память после окончания буфера кучи.

Есть второй код, с одномерным массивом - проблема та же:
Код:
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
	setlocale(LC_ALL, "Russian");
	srand(time(NULL));
	int size = 0, min_ipos = 0;
	int *arr = new int[size];
	cout << "Введите количество элементов массива: "; cin >> size;
	cout << "\t";
	for (int i = 0, min_i = 0; i < size; i++)
	{
		arr[i] = rand() % 400 + 100;
		if (i == 0) min_i = arr[0];
		if (arr[i] < min_i)
		{
			min_i = arr[i];
			min_ipos = i;
		}
		cout << arr[i] << " ";
	}
	cout << "\n";
	if (min_ipos == size-1)
	{
		arr[size - 1] = 0;
		for (int i = 0; i < size; i++) cout << arr[i] << " ";
		delete[] arr;
		return 0;
	}
	for (min_ipos; min_ipos < size; min_ipos++)
	{
		if (min_ipos != (size-1)) arr[min_ipos] = arr[min_ipos + 1];
		else break;
	}
	arr[size - 1] = 0;
	cout << "\t";
	for (int i = 0; i < size; i++)
	{
		cout << arr[i] << " ";
	}
	cout << "\n\n";
	delete[] arr;
	return 0;
	system("pause");
}
Красным выделил источник уничтожения нервных клеток. Самое интересное, что если разбить этот второй код по функциям - все работает отлично, вот пример:

Код:
#include <iostream>
#include <ctime>
using namespace std;
void assig_arr(int *arr, int size)
{
	for (int i = 0; i < size; i++)
		arr[i] = rand() % 400 + 100;
}
void findm_arr(int *arr, int size, int &min_ipos)
{
	int min_i = arr[0];
	for (int i = 1; i < size; i++)
		if (arr[i] < min_i)
		{
			min_i = arr[i];
			min_ipos = i;
		}
}
int  replg_arr(int *arr, int size, int &min_ipos)
{
	if (min_ipos == size - 1) // Если минимальное значение в массиве крайнее, то просто подставляем ноль и выходим из функции
		return arr[size - 1] = 0;
	for (min_ipos; min_ipos < size; min_ipos++) // Начинаем цикл элементом с минимальным значением
	{
		if (min_ipos != size - 1) // Если текущий элемент не равен крайнему элементу массива, копируем данные с соседнего элемента
			arr[min_ipos] = arr[min_ipos + 1];
		else break; // Во всех остальных случаях выходим из цикла (чтобы не скопировать данные, которые находятся за пределами массива)
	}
	return arr[size - 1] = 0; // После результата работы цикла, задаем крайнему элементу массива значение - ноль
}
void print_arr(int *arr, int size)
{
	cout << "\t";
	for (int i = 0; i < size; i++)
		cout << arr[i] << " ";
	cout << "\n\n";
}
void main()
{
	setlocale(LC_ALL, "Russian");
	srand(time(NULL));
	int size = 0, min_ipos = 0;
	cout << "Введите количество элементов массива: "; cin >> size;
	int *arr = new int[size]; // Генерация динамического массива, чтобы задать длинну в ходе выполнения программы
	assig_arr(arr, size); // Задаем случайные значения элементам массива (от 100 - 500)
	print_arr(arr, size); // Выводим на экран изначальный массив
	findm_arr(arr, size, min_ipos); // Поиск минимального значения
	replg_arr(arr, size, min_ipos); // Удаление мин. значения, сдвиг и присваиваем ноль в крайний элемент
	print_arr(arr, size); // Выводим на экран измененный массив
	delete[] arr; // Освобождение памяти
	system("pause");
}
Заранее спасибо!

Последний раз редактировалось c3nwen; 02.06.2018 в 01:04.
c3nwen вне форума Ответить с цитированием
Старый 02.06.2018, 01:53   #2
New man
Форумчанин
 
Регистрация: 24.01.2011
Сообщений: 774
По умолчанию

Цитата:
Сообщение от c3nwen Посмотреть сообщение
Код:
int *arr = new int[size]; 
cout << "Введите количество элементов массива: "; cin >> size;
Во втором коде: Надо делать в обратном порядке. Ты выделяешь память под массив из 0 элементов.

В первом коде то же самое. Выделяй память в процедуре crt_array().
a.k.a. Angelicos Phosphoros
Мой сайт
New man вне форума Ответить с цитированием
Старый 03.06.2018, 00:08   #3
c3nwen
 
Аватар для c3nwen
 
Регистрация: 01.06.2018
Сообщений: 9
По умолчанию

Писец... Вероятно проблема действительно в этом, чуть позже протестирую. Спасибо огромное!!!!!
c3nwen вне форума Ответить с цитированием
Старый 03.06.2018, 03:59   #4
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

А еще лучче не парится с этим. Это вообще-то массив указателей на указатели там. Просто выглядит как-бы двумерный массив....
В С лучче распределять 1-мерный n * m, а потом из индексов i/j высчитывать 1-мерный индекс, типа ptr[i * m + j].
alexzk вне форума Ответить с цитированием
Старый 10.06.2018, 16:39   #5
2Lui
Пользователь
 
Аватар для 2Lui
 
Регистрация: 14.03.2017
Сообщений: 68
По умолчанию

Ну если удалаешь двухмерный массив тогда нужно удалить сначала то что внутри него а потом сам массив и как бы обнулить его вот так
Код:
void del_array()
{
	for (int i = 0; i < rows; i++) 
       {
          delete[] _array[i];
       }
	delete[] _array;
         _array = 0;
}

Последний раз редактировалось 2Lui; 10.06.2018 в 16:42.
2Lui вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Освобождение памяти из под динамического двумерного массива Haric_110 Общие вопросы C/C++ 37 15.10.2017 04:43
Динамическое выделение памяти для двумерного массива в СИ++ прямИСТ Помощь студентам 3 19.11.2016 15:13
Правильное удаление двумерного динамического массива Gdasar C++ Builder 3 23.02.2015 02:30
Осв. памяти дин. двумерного массива kineziz Общие вопросы C/C++ 3 06.06.2012 23:43
удаление строки и столбца из двумерного массива Hitory Общие вопросы Delphi 0 06.06.2012 20:59