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

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

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

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

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


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


Курсовая работа по дисциплине

основы алгоритмизации и программирования


Выполнил:студент Золин А.С.

группа    Р-290Б

Проверил:  Трофимов С.П.

Дата:           

 

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

 

Содержание

Содержание.......................................................................................................... 2

Введение................................................................................................................. 3

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

Задание №2.............................................................................................................. 4

Задание №6.............................................................................................................. 4

Задание №8.............................................................................................................. 4

Задание №10............................................................................................................ 4

Задание №12............................................................................................................ 4

Задание №14............................................................................................................ 4

Задание №16............................................................................................................ 4

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

Задание №2.............................................................................................................. 5

Задание №6.............................................................................................................. 5

Задание №8.............................................................................................................. 6

Задание №10............................................................................................................ 8

Задание №12.......................................................................................................... 10

Задание №14.......................................................................................................... 11

Задание №16.......................................................................................................... 12

Библиографический список................................................................. 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=%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_();

}


Библиографический список

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

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

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

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

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