Возникающие при использовании динамически распределяемой памяти
1). Недоступные блоки - блоки памяти, указатели на которые потеряны. Динамическая переменная создана в блоке { }, по выходу из него память теряется, становится недоступной.
2). Висящие ссылки (никуда не указывают) - указатели на освобожденные блоки памяти. Мы выделили динамическую память по одному указателю: int *pt1=new int; а потом в процессе работы программы определили еще один указатель и ему присвоили адрес первого int *pt2=pt1; потом где-то в программе я забываю и делаю delete pt2; ….. где-то пытаюсь обратиться к pt1: *pt1=5; вот и получили висячий указатель.
3). Повторное освобождение динамической памяти. Недоступные блоки возникают после выделения памяти при присваивании указателю какого-либо другого значения или при уничтожении локального указателя после выхода из области видимости. Имею 2 указателя на 1 и тот же адрес, очищаю по обоим – ошибка.
Пример 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 уже нельзя использовать для обращения к массиву!
...
Если нет освобождения памяти, программист в зависимости от конкретной ситуации может посчитать это ошибкой, а может и нет (хотя это в любом случае уменьшает доступные ресурсы памяти), повторное освобождение безусловно ошибочно и скорее всего приведет к зависанию системы. Как правило, подобные ошибки не проявляются немедленно после появления, что затрудняет процесс отладки.
Пример 1. Написать программу учета успеваемости группы. Программа должна считать ср. бал группы и выводить на экран.
#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->midle=( 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;
}
ФАЙЛ
Язык Си "рассматривает" файл как структуру. В stdio.h содержится определение структуры файла. Определен шаблон и директива препроцессора #defile FILE struct iobuf
FILE краткое наименование шаблона файла. Некоторые системы используют директиву typedef для установления этого соответствия.
typedef struct iobuf FILE
Дата добавления: 2016-02-02; просмотров: 804;