Рефетека.ру / Информатика и програм-ие

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

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

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

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

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

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

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

Екатеринбург 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=%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_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 %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;

 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("Не хватает памяти под 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)))) 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 ("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 (int i=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;

 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 ("%fn",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.

Для подготовки данной работы были использованы материалы с сайта http://www.ed.vseved.ru/


Рефетека ру refoteka@gmail.com