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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 07.11.2018, 13:59   #1
niktit
 
Регистрация: 07.11.2018
Сообщений: 6
По умолчанию Работа с динамическим массивом в Си. Разделение по функциям

Всем привет. Собственно необходимо произвести аллокацию, инициализацию и вывод двумерного массива. Вроде всё легко за исключением того, что не получается отдельной функцией произвести вывод массива.
Если содержимое show_matrix разместить в init_matrix, то всё норм, но нужно по разным функциям распределить. Вроде же по указателям делаю запрос на вывод и заполняю по ним.
Код:
#include <stdio.h>
#include <malloc.h>

int init_matrix(int s, int c, int **a);//Прототипы
int show_matrix(int s, int c, int **a);
int clear_matrix(int c, int **a);

int main()
{
  int str = 0;
  int col = 0;
  int **arr = NULL;
  
  	printf("\r\nEntered count string: ");
  	scanf("%d", &str);
  	printf("\r\nEntered count column: ");
  	scanf("%d", &col);

  		init_matrix(str, col, arr);
  		show_matrix(str, col, arr);
  		clear_matrix(str, arr);
  		getchar();
  		getchar();
  return 0;
}

int init_matrix(int s, int c, int **a) // Аллокация и инициализация массива
{

a = (int**)malloc(s * sizeof(int));
	for(int i = 0; i < s; i++)//Идём по строкам
	{
		a[i] = (int*)malloc(c * sizeof(int));
		printf("\r\n");
		for(int j = 0; j < c; j++)// Проходимся по столбам
		{
			printf("arr[%d][%d] = ", i, j);
			scanf("%d",&a[i][j]);
		}
	}
	return **a;
}

int show_matrix(int s, int c, int **a)
{

	for(int i = 0; i < s; i++) // выводим строки
	{
		printf("\r\n");
		for(int j = 0; j < c; j++) // столбцы
		{
			printf("%5d", a[i][j]);
		}
	}
}

int clear_matrix(int s, int **a)//Освобождаем память
{
	for(int i = 0; i < s; i++)
	{
		free(&a[i]);
	}
	free(a);
	a = NULL;
}
niktit вне форума Ответить с цитированием
Старый 07.11.2018, 14:15   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,707
По умолчанию

Посмотрите в отладчике свою матрицу после функции init. И в первом выделении памяти нужен int* в сайзофе.
p51x вне форума Ответить с цитированием
Старый 08.11.2018, 13:31   #3
niktit
 
Регистрация: 07.11.2018
Сообщений: 6
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Посмотрите в отладчике свою матрицу после функции init. И в первом выделении памяти нужен int* в сайзофе.
В sizeof исправил и убрал return **a в init_matrix т.к. не подставляю функцию для переменных и прочего. Скачал OllyDbg v1.10 с оф сайта. Да там же разобрано в асм всё. Пока в дебаггере мало чего разобрал, но заливаюсь по-немногу этим. Раньше только работал в PHP и опыт в нём достаточный, а тут решил на прикладное прог. перейти и выбрал Си изучать. Просто не понятно мне почему прога вылетает на функции show_matrix, а если её тело пихнуть в init, то всё нормально. Ведь я же не на прямую, а с указателями да адресами работаю. Видимо не до конца разобрался как в Си массивы варятся. Ладно пойду дальше разбирать работу с указателями.
niktit вне форума Ответить с цитированием
Старый 08.11.2018, 13:35   #4
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,707
По умолчанию

Зачем вам оля? У вас есть ИДЕ с отладчиком и исходными кодами...

Я же зря говорил - посмотрите на указатель до и после вызова инита.
p51x вне форума Ответить с цитированием
Старый 08.11.2018, 20:59   #5
niktit
 
Регистрация: 07.11.2018
Сообщений: 6
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Зачем вам оля? У вас есть ИДЕ с отладчиком и исходными кодами...

Я же зря говорил - посмотрите на указатель до и после вызова инита.
Пишу в саблайме, а компилирую через cmd. на днях codeblock поставлю или visualstudio.
Решил проверить указатель до и после, а там после 00000000.
Код:
	printf("\r\nUntil that init_matrix: %p",arr);
        init_matrix(str, col, arr);
        printf("\r\nAfter that init_matrix: %p",arr);
Но вот внутри init
Цитата:
printf("\r\nComplete allocation of the matrix: %p",a);
вывело адрес как и ожидалось.
Т.е. функция init_matrix не внесла адрес в указатель arr.
Если провести выделение памяти до init, то
Цитата:
arr = (int**)malloc(str * sizeof(int*));
printf("\r\nAfter that init_matrix: %p",arr);
init_matrix(str, col, arr);
printf("\r\nAfter that init_matrix: %p",arr);
show_matrix(str, col, arr);
clear_matrix(str, arr);
и в init удалить первое выделение памяти, то всё работает как надо. Но так думаю не совсем будет правильно. Я думал, что если в функцию передать аргумент в виде указателя на указатели, то с ним в дальнейшем можно работать в других функциях т.к. функция впишет именно в него адрес. Ладно буду дальше погружаться, хочу всё таки полностью память выделять в отдельной функции. Спасибо.
niktit вне форума Ответить с цитированием
Старый 08.11.2018, 21:31   #6
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,707
По умолчанию

Цитата:
Сообщение от niktit Посмотреть сообщение
Я думал, что если в функцию передать аргумент в виде указателя на указатели, то с ним в дальнейшем можно работать в других функциях т.к. функция впишет именно в него адрес.
Так. Если вам надо в функции изменить переменную, то нужен указатель или ссылка.

А теперь внимание вопрос: если вам надо изменить указатель то, что надо передать? А если в вашем случае указатель на указатель?
p51x вне форума Ответить с цитированием
Старый 09.11.2018, 08:08   #7
niktit
 
Регистрация: 07.11.2018
Сообщений: 6
По умолчанию

Ну т.к указатель хранит только адрес, то и передавать в него нужно только адрес. В моём случае указатель хранит адрес массива адресов на массивы которые уже хранят числа.

Значит при вызове init мне надо передать адрес указателя в неё. Т.е. уже создать массив с указателями до вызова init как я делал выше ну или внести этот адрес из init в указатель объявленный в main int ** arr = NULL; и сделать это через ссылку.
niktit вне форума Ответить с цитированием
Старый 20.11.2018, 20:25   #8
niktit
 
Регистрация: 07.11.2018
Сообщений: 6
По умолчанию

Появилось время разобраться с этим вопросом и вроде получилось. Просто объявил в функции возвращение указателя на массив указателей и всё заработало. Приведу код ниже так на всякий. Может кому поможет.
Код:
#include <stdio.h>
#include <malloc.h>

int ** init_matrix(int s, int c, int **a);//Прототипы
int show_matrix(int s, int c, int **a);
int clear_matrix(int c, int **a);

int main()
{
  int str = 0;
  int col = 0;
  int **arr = NULL;
  
  	printf("\r\nEntered count string: ");
  	scanf("%d", &str);
  	printf("\r\nEntered count column: ");
  	scanf("%d", &col);

  		arr = init_matrix(str, col, arr);
  		show_matrix(str, col, arr);
  		clear_matrix(str, arr);
  		getchar();
  		getchar();
  return 0;
}

int ** init_matrix(int s, int c, int **a) // Аллокация и инициализация массива
{

a = (int**)malloc(s * sizeof(int*));
	for(int i = 0; i < s; i++)//Идём по строкам
	{
		a[i] = (int*)malloc(c * sizeof(int));
		printf("\r\n");
		for(int j = 0; j < c; j++)// Проходимся по столбам
		{
			printf("arr[%d][%d] = ", i, j);
			scanf("%d",&a[i][j]);
		}
	}
return a;
}

int show_matrix(int s, int c, int **a)
{

	for(int i = 0; i < s; i++) // выводим строки
	{
		printf("\r\n");
		for(int j = 0; j < c; j++) // столбцы
		{
			printf("%5d", a[i][j]);
		}
	}
}

int clear_matrix(int s, int **a)//Освобождаем память
{
	for(int i = 0; i < s; i++)
	{
		free(&a[i]);
	}
	free(a);
	a = NULL;
}
niktit вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с двумерным динамическим массивом Fylh_if Общие вопросы C/C++ 1 15.12.2014 08:14
Работа с Динамическим массивом эдитов Xatiko Помощь студентам 4 05.03.2013 11:29
Работа с двумерны динамическим массивом Serega_86 Помощь студентам 2 02.09.2012 15:40
(delphi) работа с динамическим массивом anubiss Помощь студентам 0 21.05.2012 21:09
Работа с динамическим массивом sand Общие вопросы C/C++ 3 22.08.2008 12:48