Инициализаторы с операцией new
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

 

Другим преимуществом операции new по сравнению с malloc является возможность инициализации. При отсутствии явных инициализаторов объект, создаваемый new, содержит непредсказуемые данные ("мусор"). Объекты, распределяемые new, за исключением массивов, могут инициализироваться соответствующим выражением в скобках:

int_ptr = new int(3);

Для очистки выделенной памяти операцией new можно использовать функцию meset(), объявленную в <mem.h>. Ей передаются 3 параметра: адрес очищаемой памяти, символ для очистки, количество байт.

 

#include <string.h>                          

#include <stdio.h>                           

#include <mem.h>                             

int main(void) {

char buffer[] = "Hello world\n";          

  printf("Буфер до memset: %s\n", buffer);

  memset(buffer, '*', strlen(buffer) - 1);  

  printf("Буфер после memset: %s\n", buffer);

  return 0;                                 

}

                              

Ошибки при использовании динамичской памяти

 

1). Недоступные блоки - блоки памяти, указатели на которые потеряны.

2). Висящие ссылки - указатели на освобожденные блоки памяти.

3). Повторное освобождение динамической памяти. Недоступные блоки возникают после выделения памяти при присваивании указателю какого- либо другого значения или при уничтожении локального указателя после выхода из области видимости.

 

Пример 1:

int *a1, *a2;

a1 = new int[1000];        //выделили память

...                               //что-то делаем

a1 = a2;                     //ошибка - присвоение а1 другого

   //значения - память недоступна

Пример 2:

 void func(void)

 {

int * a1;

a1 = new int[1000];

...

 } //ошибка - при выходе из функции автоматически   

//уничтожен a1,а память, тем не менее, осталась

//занята и недоступна. 

Необходимо следить за указателями на выделенную память:

 int * c;

 void func1(void) {

int * a1;

a1 = new int[1000];

c = a1; //если данные по адресу a1 необходимы вне func1

...    //иначе освободить перед выходом из функции

 }

 void func2(void)

 {

...

delete []c;

 }

Висящие ссылки возникают при освобождении памяти, на которую указывает более чем 1 указатель:

 int *a = new int[1000];

 int *a1 = a;

 ...

 delete []a;

 d = *(a1+50);         //опасно - a1 уже нельзя использовать для обращения к 

 //массиву!

 ...

 

Если нет освобождения памяти, программист в зависимости от конкретной ситуации может посчитать это ошибкой, а может и нет (хотя это в любом случае уменьшает доступные ресурсы памяти), повторное освобождение безусловно ошибочно и скорее всего приведет к зависанию системы. Как правило, подобные ошибки не проявляются немедленно после появления, что затрудняет процесс отладки.

 

Написать программу учета успеваемости группы. Программа должна считать ср. бал группы и выводить на экран.

#include <stdio.h>

#include <conio.h>

#include <iostream.h>

void main(void) {

       int i,j,n;

       float varsum=0;

       struct stud { char fio[15]; char name[10];

                       struct exam { int val1; int val2;

   int val3; int val4;}estimate;

                                              float midle;

                                           };

                   puts(«введите кол-во студентов”);

                   cin>>n;

                   struct stud *pgroup=new struct stud[n];

                   for(i=0; i<n; i++) {

                               printf(“Введите данные по %d студенту\n”,i+1);

                               cout<< “Фамилия:”;

                               gets(pgroup->fio);

                               cout<< “Имя:”;

                               gets(pgroup->name);

                               cout<< “Оценка за 1-й экзамен:”;

                               gets(pgroup->estimate.val1);

                               cout<< “Оценка за 2-й экзамен:”;

                               gets(pgroup->estimate.val2);

                               cout<< “Оценка за 3-й экзамен:”;

                               gets(pgroup->estimate.val3);

                               cout<< “Оценка за 4-й экзамен:”;

                               gets(pgroup->estimate.val4);

pgroup->middle = ( pgroup->estimate.val1+pgroup->estimate.val2+ pgroup->estimate.val3+ pgroup->estimate.val4)/4;

cout<<”Средний бал ”<< pgroup->fio<< pgroup->name<< pgroup->midle<<endl;

                               varsum+= pgroup->midle;

                   }

                   cout<<»Средний балл по группе”<<varsum/n<<endl;

                   delete[] pgroup;

       }

 

ФАЙЛ

 

Язык Си "рассматривает" файл как структуру. В stadio.h содержится определение структуры файла. Определен шаблон и директива препроцессора #defile FILE struct iobuf

FILE краткое наименование шаблона файла. Некоторые системы используют директиву typedef для установления этого соответствия.

typedef struct iobuf FILE

 

Открытие файла fopen()

 

Функцией управляют три параметра.

FILE *in;               //указатель потока

Для связывания указателя с файлом служит функция открытия файла fopen(), которая объявлена в заголовочном файле <stdio.h>.

in = fopen (" test ", " r ");

1 параметр - имя открываемого файла

2 параметр -

"r"-по чтению   "r+"-чтение и запись

"w"-по записи   "w+"-запись и чтение, если файл уже был, он перезаписываетя

"a"-дозапись      "a+"-чтение и дозапись, если файла еще не было, он создается

"b"-двоичный файл

"t"-текстовый файл

in является указателем на файл "test". Теперь будем обращаться к файлу через этот указатель.

Если файл не был открыт (его нет, нет места на диске), то возвращается в указатель 0.

if((in=fopen("test", "r"))==0)

puts("Ошибка открытия файла");

Можно по другому

in=fopen("test", "r");

if (!in)

puts("Ошибка открытия файла");

 

Закрытие файла fclose()

 

fclose(FILE *stream);    //Если файл закрыт успешно, то возвращается 0 иначе -1.

 

Дата: 2018-12-21, просмотров: 347.