|
Динамическое распределение памяти
Динамическое распределение памяти
Содержание
*
Введение
*
Руководство пользователя
*
Задание №2
*
Задание №6
*
Задание №8
*
Задание №10
*
Задание №12
*
Задание №14
*
Задание №16
*
Руководство программиста
*
Задание №2
*
Задание №6
*
Задание №8
*
Задание №10
*
Задание №12
*
Задание №14
*
Задание №16
*
Библиографический список
*
Введение
Целью работы является демонстрация работы с динамической памятью на примере программ разработанных к заданиям 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.
|
|
|