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


           Министерство высшего и профессионального образования РФ
              Уральский государственный технический университет
                         Радиотехнический факультет
              Кафедра “Автоматика и информационные технологии”



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



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



                            Выполнил:студент Золин А.С.
                                        группа    Р-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 
#include 
#include 
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 
#include 
#include 
#include 
#include 
//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
#include 
#include 
#include 
//Структура 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;im;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;im;i++)
 {
  if (matr->ptr[i]) free(matr->ptr[i]);
 }
 if (matr->ptr) free(matr->ptr);
}


                                 Задание №10


#include 
#include 
#include 
#include 
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
#include 
#include 
#include 
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;im;i++)
 {
   if (!(matr->ptr[i]=(double *)malloc(sizeof(double)*(matr->n))))
return 0;
 }
 return 1;
}
void FreeMatr(Matr *matr)
{
 for (int i=0;im;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;im;i++)
 {
    for (int j=0;jn;j++) (matr->ptr[i][j])=M[i][j];
 }
}
double OctNorm(Matr *matr)
{
 double max=0;
 double a=0;
 for (int i=0;im;i++)
 {
  max+=matr->ptr[i][0];
 }
 for (int j=0;jn;j++)
 {
  for (i=0;im;i++)
  {
   a+=matr->ptr[i][j];
  }
  if (a>max) max=a;
  a=0;
 }
 return max;
}


                                 Задание №14


#include 
#include 
#include 
#include 

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 
    #include 
    #include 
    #include 
    #include 
    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.