Реферат: Динамическое распределение памяти
Министерство высшего ипрофессионального образования РФ
Уральский государственный технический университет
Радиотехнический факультет
Кафедра “Автоматикаи информационные технологии”
Динамическоераспределение памяти
Курсоваяработа по дисциплине
основы алгоритмизации и программирования
Выполнил: студент Золин А.С.
группа Р-290Б
Проверил: Трофимов С.П.
Дата:
Екатеринбург 2000
СодержаниеTOC o«1-3» Содержание… PAGEREF _Toc376724409 h 2
Введение… PAGEREF _Toc376724410 h 3
Руководство пользователя… PAGEREF _Toc376724411 h 4
Задание №2… PAGEREF _Toc376724412 h 4
Задание №6… PAGEREF _Toc376724413 h 4
Задание №8… PAGEREF _Toc376724414 h 4
Задание №10… PAGEREF _Toc376724415 h 4
Задание №12… PAGEREF _Toc376724416 h 4
Задание №14… PAGEREF _Toc376724417 h 4
Задание №16… PAGEREF _Toc376724418 h 4
Руководство программиста… PAGEREF _Toc376724419 h 5
Задание №2… PAGEREF _Toc376724420 h 5
Задание №6… PAGEREF _Toc376724421 h 5
Задание №8… PAGEREF _Toc376724422 h 6
Задание №10… PAGEREF _Toc376724423 h 8
Задание №12… PAGEREF _Toc376724424 h 10
Задание №14… PAGEREF _Toc376724425 h 11
Задание №16… PAGEREF _Toc376724426 h 12
Библиографический список… PAGEREF _Toc376724427 h 15
Введение
Целью работыявляется демонстрация работы с динамической памятью на примере программразработанных к заданиям 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=%pn»,x); // Вывод на экран адреса начала блокадля *x
printf(«Adress of *y=%pn»,y); // --//-- *y
printf(«Adress of *z=%pn»,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_var20
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 %in»,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;
voidSetRazm(int mm,int nn)
{
m=mm;
n=nn;
}
};
//Структура Matr1, которая содержит размеры матрицы,а также двумерный
//массив элементов матрицы и функцию для заданияразмеров матрицы
struct Matr2{
int m,n;
int **ptr;
voidSetRazm(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
Matr2M2; //Создание экземпляра Matr2
M1.SetRazm(2,2); //Задание размеров Matr1
M2.SetRazm(2,2); //--//--Matr2
if(!DinMatr1(&M1)) //Выделениепамяти для Matr1
{
printf(«Не хватает памяти под M1n»);
exit (1);
}
if(!DinMatr2(&M2)) //--//--Matr2
{
printf(«Не хватает памяти под M2n»);
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)))) return0;
return 1;
}
int DinMatr2 (Matr2 *matr)
{
if(!(matr->ptr=(int **)malloc(sizeof(int *)*(matr->m)))) return 0;
for (inti=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 (inti=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;
intc,m=0,n=0;
mas=(char**)malloc(sizeof(char *)); //Выделениепамяти под первое число
mas[0]=(char*)malloc(sizeof(char)); //Выделениепамяти под первую позицию //цифрыв числе
printf(«Intputn»);
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(«Outputn»);
for (inti=0;i<m;i++) printf ("%sn",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;
voidSetRazm(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();
doubleM_[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("%fn",OctNorm(&M));
FreeMatr(&M);
return 0;
}
int DinMatr (Matr *matr)
{
if(!(matr->ptr=(double **)malloc(sizeof(double *)*(matr->m)))) return 0;
for (inti=0;i<matr->m;i++)
{
if(!(matr->ptr[i]=(double *)malloc(sizeof(double)*(matr->n)))) return 0;
}
return 1;
}
void FreeMatr(Matr *matr)
{
for (inti=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 (inti=0;i<matr->m;i++)
{
for (intj=0;j<matr->n;j++) (matr->ptr[i][j])=M[i][j];
}
}
double OctNorm(Matr *matr)
{
double max=0;
double a=0;
for (inti=0;i<matr->m;i++)
{
max+=matr->ptr[i][0];
}
for (intj=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 heapN=%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»))) return0;
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_();
}
Библиографический список
1. Трофимов С.П.Программирование в Си. Динамическое распределение памяти:
Метод.указания. Екатеринбург: изд-во УГТУ, 1998.
2. Трофимов С.П.Программирование в Си. Организация ввода-вывода:
Метод.указания. Екатеринбург: изд-во УГТУ, 1998.
3. Хинт К. Си без проблем.Руководство пользователя. М.: Бином, 1997.