Динамическое распределение памяти

Динамическое распределение памяти

Курсовая работа по дисциплине основы алгоритмизации и программирования студента Золин А.С.

Министерство высшего и профессионального образования РФ

Уральский государственный технический университет

Радиотехнический факультет

Кафедра “Автоматика и информационные технологии”

Екатеринбург 2000

Введение

Целью работы является демонстрация работы с динамической памятью на примере программ разработанных к заданиям 2, 6, 8, 10, 12, 14, 16 из методического указания [1].

Динамическое распределение памяти предоставляет программисту большие возможности при обращении к ресурсам памяти в процессе выполнения программы, и корректная работа программы с динамической памятью в существенной степени зависит от знания функций для работы с ней.

Руководство пользователя

Задание №2

Для того чтобы убедиться что для каждого из однобайтовых данных в куче выделено 16 байт т.е. 1 параграф нужно сравнить три адреса, которые появяться на экран в рез-те действия этой программы. Если числа в этих адресах стоящие до двоеточия увеличиваютя (от первого к последнему) на еденичку, то это означает что на каждый блок выделен один параграф в куче = 16 байт. Для получения этих адресов в отладчике достаточно нажать Alt+F4 (в режиме отладчика) затем в появившемся запросе ввести *x появится меню, вверху которого и будет нужный адрес, аналогично для *y, *z.

Задание №6

Программа выделяет память под 20 переменных типа int, заполняет их случайными числами из интервала [-3;7] и выводит их на экран.

Задание №8

Программа хранит матрицы в виде двух структур: 

		Struct Matr1{int m, n; int *ptr};

		Struct Matr2{int m, n; int **ptr};

И выделяет память под них с помощью следующих функций:

		Int DinMatr1(Matr1 *matr);

		Int DinMatr2(Matr2 *matr);

Задание №10

Программа получает с клавиатуры натуральные числа, сохраняя их в куче, конец ввода – число 0. По окончании ввода числа выводятся на экран.

Задание №12

Программа вычисляет октоэдрическую норму матрицы произвольных размеров.

Задание №14

Программа вычисляет общий размер свободной кучи.

Задание №16

Программа выполняет считывание матрицы произвольных размеров из файла (разделителями являются пробелы), вывод этой матрицы на экран, а также запись в файл.

Руководство программиста

В этом разделе будут приведены листинги программ с комментариями.

Задание №2

#include <stdio.h>			

#include <alloc.h>			

#include <conio.h>			

int main(void)			

{			

 char *x,*y,*z;		//Объявление переменных

 x=(char *)malloc(sizeof(char));		//Выделение динамической памяти для *x	

 y=(char *)malloc(sizeof(char));		// --//-- *y			

 z=(char *)malloc(sizeof(char));		// --//-- *z			

 clrscr();							// Очистка экрана

 printf("Adress of *x=%p\n",x); 		// Вывод на экран адреса начала блока для *x	

 printf("Adress of *y=%p\n",y); 		// --//-- *y			

 printf("Adress of *z=%p\n",z); 		// --//-- *z			

 free (z);							// Освобождение блока выделенного для *z

 free (y); 				// --//-- *y			

 free (x); 				// --//-- *x

 /*

 Для того чтобы убедиться что для каждого из однобайтовых данных в куче

 выделено 16 байт т.е. 1 параграф нужно сравнить три адреса, которые поя-

 вяться на экран в рез-те действия этой программы. Если числа в этих адресах

 стоящие до двоеточия увеличиваютя (от первого к последнему) на еденичку, то

 это означает что на каждый блок выделен один параграф в куче = 16 байт.

 Для получения этих адресов в отладчике достаточно нажать Alt+F4 (в режиме

 отладчика) затем в появившемся запросе ввести *x появится меню, вверху

 которого и будет нужный адрес, аналогично для *y, *z.

 */

 return 0;

}

Задание №6

#include <stdio.h>		

#include <conio.h>		

#include <alloc.h>		

#include <process.h>		

#include <stdlib.h>		

//N_var - число элементов массива		

#define N_var 20		

main()		

{		

clrscr();		

//Инициализация генератора случ. чисел

randomize();		

int *mas;		

//Выделение памяти под массив		

if (!(mas=(int *)malloc(sizeof(int	)*N_var)))

{		

printf ("Не достаточно памяти для выделения массива\n");

exit (1);		

}		

//Заполнение массива случ. числами в диапазоне от -3 до 7 с одновременным

//выводом на экран		

for (int i=0;i<N_var;i++)		

{		

mas[i]=random(11)-3;		

printf("N=%i %i\n",i,mas[i]);		

}		

//Освобождение памяти из под масси	ва	

free (mas);		

return 0;		

}		

Задание №8

#include <stdio.h>

#include <conio.h>

#include <alloc.h>

#include <process.h>

//Структура Matr1, которая содержит размеры матрицы, а также одномерный

//массив элементов матрицы и функцию для задания размеров матрицы

struct Matr1{

 int m,n;

 int *ptr;

 void SetRazm(int mm,int nn)

 {

 m=mm;

 n=nn;

 }

};

//Структура Matr1, которая содержит размеры матрицы, а также двумерный

//массив элементов матрицы и функцию для задания размеров матрицы	

struct Matr2{	

 int m,n;	

 int **ptr;	

 void SetRazm(int mm,int nn)	

 {	

 m=mm;	

 n=nn;	

 }	

};	

int DinMatr1 (Matr1 *matr);		//функция выделения памяти для Matr1

int DinMatr2 (Matr2 *matr); 	//функция выделения памяти для Matr2	

void FreeMatr1(Matr1 *matr); 	//функция освобождения памяти из под Matr1	

void FreeMatr2(Matr2 *matr); 	//функция освобождения памяти из под Matr2	

main()	

{	

 clrscr();			

 Matr1 M1;					//Создание экземпляра Matr1

 Matr2 M2; 			//Создание экземпляра Matr2			

 M1.SetRazm(2,2);				//Задание размеров Matr1	

 M2.SetRazm(2,2); 		//--//-- Matr2			

 if (!DinMatr1(&M1))			//Выделение памяти для Matr1	

 {			

 printf("Не хватает памяти под M1\n");			

 exit (1);			

 }			

 if (!DinMatr2(&M2))			//--//-- Matr2	

 {			

 printf("Не хватает памяти под M2\n");			

 exit (1);			

 }			

 FreeMatr1 (&M1);				//Освобождение памяти из под Matr1

 FreeMatr2 (&M2);				//--//-- Matr2

 return 0;		

}		

int DinMatr1 (Matr1 *matr)		

{		

 if (!((matr->ptr)=(int *)malloc(sizeof(int)*(matr->m)*(matr->n)))) return 0;		

 return 1;		

}		

int DinMatr2 (Matr2 *matr)		

{		

 if (!(matr->ptr=(int **)malloc(sizeof(int *)*(matr->m)))) return 0;		

 for (int i=0;i<matr->m;i++)		

 {		

 if (!(matr->ptr[i]=(int *)malloc(sizeof(int)*(matr->n)))) return 0;		

 }

 return 1;

}

void FreeMatr1(Matr1 *matr)

{

 if (matr->ptr) free (matr->ptr);

}

void FreeMatr2(Matr2 *matr)

{

 for (int i=0;i<matr->m;i++)

 {

 if (matr->ptr[i]) free(matr->ptr[i]);

 }

 if (matr->ptr) free(matr->ptr);

}

Задание №10

#include <stdio.h>				

#include <conio.h>				

#include <alloc.h>				

#include <process.h>				

main()				

{				

 clrscr();				

 char **mas;				

 int c,m=0,n=0;				

 mas=(char **)malloc(sizeof(char *));	//Выделение памяти под первое число				

 mas[0]=(char *)malloc(sizeof(char));	//Выделение памяти под первую позицию						 				//цифры в числе

 printf ("Intput\n");				

 while ((c=getch())-'0')	 			//Пока не ввели 0			

 {				

 if (c==13) 			//При нажатии Enter выделение памяти				

 { 				//под новое число			

 mas[m][n]=0;			

 m++;			

 if (!(mas=(char **)realloc(mas,sizeof(char *)*(m+1))))			

 {			

 printf ("Не хватает памяти\n");			

 exit(1);			

 }			

 n=0;			

 putch(10);			 			//Перевод карретки и перевод строки

 putch(13); 			//при выводе на экран			

 }			

 if ((c<'0')||(c>'9')) continue; 		//Проверка на ввод только цифр			

 if ((!n)&&(m))		 			//Выделение памяти под первую позицию	

 { 				//в следующем числе			

 if(!(mas[m]=(char *)malloc(sizeof(char)) ))			

 {

 printf ("Не хватает памяти\n");

 exit(1);

 }

 }

 mas[m][n]=c; 			//Занесение цифры на нужную позицию

 n++; 			//в число

 if (n) 				//Выделение памяти под следующую

 { 				//позицию в числе

 if (!(mas[m]=(char *)realloc(mas[m],sizeof(char)*(n+1))))

 {

 printf ("Не хватает памяти\n");

 exit(1);

 }

 }

 putch (c); 			//Вывод цифры на экран

 }

 printf ("Output\n");

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

//Вывод всех чисел на экран

 for (i=0;i<m;i++) if (mas[i]) free(mas[i]); 

 //Освобождение памяти

 if (mas) free(mas);

 return 0;

}

Задание №12

#include <stdio.h>

#include <conio.h>

#include <alloc.h>

#include <process.h>

struct Matr{

 int m,n;

 double **ptr;

 void SetRazm(int mm,int nn)

 {

 m=mm;

 n=nn;

 }

};

int DinMatr (Matr *matr); 			//функция выделения памяти для Matr

void FreeMatr(Matr *matr); 		//функция освобождения памяти из под Matr

void Setelem(Matr *matr,double M[3][3]);

//функция заполнения матрицы элементами

double OctNorm(Matr *matr); 		//функция вычисления нормы матрицы

main()

{

 clrscr();

 double M_[3][3]={{1,2,3},{4,5,6},{7,8,9}};

 Matr M;

 M.SetRazm(3,3);

 if (!DinMatr(&M))

 {

 printf ("Не хватает памяти для матрицы\n");

 exit(1);

 }

 Setelem(&M,M_);

 printf ("%f\n",OctNorm(&M));

 FreeMatr(&M);

 return 0;

}

int DinMatr (Matr *matr)

{

 if (!(matr->ptr=(double **)malloc(sizeof(double *)*(matr->m)))) return 0;

 for (int i=0;i<matr->m;i++)

 {

 if (!(matr->ptr[i]=(double *)malloc(sizeof(double)*(matr->n)))) return 0;

 }

 return 1;

}

void FreeMatr(Matr *matr)

{

 for (int i=0;i<matr->m;i++)

 {

 if (matr->ptr[i]) free(matr->ptr[i]);

 }

 if (matr->ptr) free(matr->ptr);

}

void Setelem(Matr *matr,double M[3][3])

{

 for (int i=0;i<matr->m;i++)

 {

 for (int j=0;j<matr->n;j++) (matr->ptr[i][j])=M[i][j];

 }

}

double OctNorm(Matr *matr)

{

 double max=0;

 double a=0;

 for (int i=0;i<matr->m;i++)

 {

 max+=matr->ptr[i][0];

 }

 for (int j=0;j<matr->n;j++)

 {

 for (i=0;i<matr->m;i++)

 {

 a+=matr->ptr[i][j];

 }

 if (a>max) max=a;

 a=0;

 }

 return max;

}

Задание №14

#include <stdio.h>				

#include <alloc.h>				

#include <conio.h>				

#include <process.h>				

void main(void)				

{				

 long N=1;				

 char *A;				

 A=(char *)calloc(N,1024);	//Выделение в куче места			

 do				

 {				

 free(A); 				//Освобождение массива	

 A=(char *)calloc(N,1024);	//Выделение памяти под больший массив			

 N++;					//Увеличение счетчика

 }		

 while(A!=NULL); 		//Продолжать пока память выделяется

 printf("\nMaximum size of heap N=%iKb",N);//Вывод результатов		

}		

Задание №16

#include <stdio.h>

#include <conio.h>

#include <alloc.h>

#include <process.h>

#include <stdlib.h>

struct MATR

{

 int n,m;

 double **ptr;

 int read_(char name[80])

 {

	FILE *pf;

	int i=0,j=0;

	char c;

	char num[10];

	int pos=0,flag=1;

	m=0;

	n=0;

	if (!(pf=fopen(name,"rt"))) return 0;

	ptr=(double **)malloc(sizeof(double *));

	ptr[0]=(double *)malloc(sizeof(double));

	while ((c=fgetc(pf))!=EOF)

	{

	 if (((c>='0')&&(c<='9'))||(c=='.'))

	 {

		num[pos]=c;

		pos++;

		flag=1;

	 }

	 if ((c==' ')&&(flag))

	 {

		flag=0;

		num[pos]=0;

		ptr[i][j]=atof(num);

		j++;

		ptr[i]=(double *)realloc(ptr[i],sizeof(double)*(j+1));

		pos=0;

	 }

	 if ((c=='\n')&&(flag))

	 {

		flag=0;

		num[pos]=0;

		ptr[i][j]=atof(num);

		i++;

		ptr=(double **)realloc(ptr,sizeof(double *)*(i+1));

		ptr[i]=(double *)malloc(sizeof(double));

		j=0;

		pos=0;

	 }

	 if (i>n) n=i;

	 if (j>m) m=j;

	}

	n--;

	fclose (pf);

	return 1;

 }

 void free_()

 {

 for(int i=0;i<=n;i++) free(ptr[i]);

 free (ptr);

 }

 void print_()

 {

 for (int i=0;i<=n;i++)

 {

 for (int j=0;j<=m;j++)

 {

 printf ("%8.3f ",ptr[i][j]);

 }

 printf ("\n");

 }

 }

 int write_(char name[80])

 {

 FILE *pf;

 if (!(pf=fopen(name,"wt"))) return 0;

 for (int i=0;i<=n;i++)

 {

 for (int j=0;j<=m;j++)

 {

 fprintf (pf,"%f ",ptr[i][j]);

 }

 fprintf (pf,"\n");

 }

 fclose (pf);

 }

};

void main()

{

 clrscr();

 MATR A;

 A.read_("C:\\mas.txt");

 A.print_();

 A.write_("C:\\out.txt");

 A.free_();

}

Список литературы

Трофимов С.П. Программирование в Си. Динамическое распределение памяти:

 Метод. указания. Екатеринбург: изд-во УГТУ, 1998.

Трофимов С.П. Программирование в Си. Организация ввода-вывода:

 Метод. указания. Екатеринбург: изд-во УГТУ, 1998.

Хинт К. Си без проблем. Руководство пользователя. М.: Бином, 1997.