Ошибка исполнения код возврата

kiff20072008

61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

1

19.04.2014, 00:14. Показов 19330. Ответов 18

Метки нет (Все метки)


Есть программа калькулятор
и в ней в случае нехватки памяти выводится соответствующая ошибка
однако проверяющий сказал мне что у меня нарушение доступа к памяти
смоделировать нехватку я не могу
анализируя код найти где у меня это нарушение не могу

Кликните здесь для просмотра всего текста

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <stdio.h> #include <string.h> #include <stdlib.h>       #include "calculator.h"       int getstring(FILE *file, char **buffer) {     int n = 1, c = EOF, i = 0;     if (feof(file))         return 1;     if ((*buffer = (char*) malloc(SIZE_ALLOC_MEMORY * sizeof(char) *n)) == NULL)     {         if ((c = fgetc(file)) == EOF)             return 1;         if (c == 'n')         {             SetError(no_memory);             return 0;         }         while (((c = fgetc(file)) != 'n') && (c!=EOF) )         {             ;         }         SetError(no_memory);         return 0;     }     while ((c = fgetc(file)) != 'n')     {         if (c == EOF)             break;         if (c > 255 || c < 0)         {             printf("ERROR: wrong simbol");             return 0;         }         if (i >= (SIZE_ALLOC_MEMORY * n - 1))         {             char *temp;               n++;             if ((temp = (char *) realloc(*buffer, sizeof(char) * SIZE_ALLOC_MEMORY * n)) == NULL)             {                 while (((c = fgetc(file)) != 'n') && (c != EOF) )                 {                     ;                 }                 SetError(no_memory);                 return 0;             }             *buffer = temp;         }         (*buffer)[i] = (char) c;         i++;     }     if (i <= (SIZE_ALLOC_MEMORY * n - 1))         (*buffer)[i] = 0;     return 0; }   int main(int Argc, char *Argv[]) {     FILE *file=stdin;     char *buffer = NULL;     char *bufferPtr;             if (Argc == 2)     {         fopen_s(&file, Argv[1], "rt");           if (file == NULL)         {             printf("nERROR:NO FILE");             return 1;         }     }     if (Argc > 2)     {         printf("nERROR: TOO MUCH ARGUMENTS");         return 1;     }     while (!getstring(file, &buffer))     {           if (IsError())         {             if (feof(file))                 printf("ERROR: %s",  GetLastErrorDescription());             else                 printf("ERROR: %sn", GetLastErrorDescription());             SetError(No_error);             if (buffer != NULL)                 free(buffer);             continue;         }          bufferPtr = buffer;           while (IS_SPACE(*bufferPtr))             bufferPtr++;         if (*bufferPtr == 0 || (bufferPtr[0] == '/' && bufferPtr[1] == '/'))         {             if (feof(file))                 printf("%s", buffer);             else                 printf("%sn", buffer);         }         else         {             double res;             res = Calculator(bufferPtr);             ClearVarTable();             if (IsError())             {             if (feof(file))                 printf("%s == ERROR: %s", buffer, GetLastErrorDescription());             else                 printf("%s == ERROR: %sn", buffer, GetLastErrorDescription());             SetError(No_error);             }             else             if (feof(file))                 printf("%s == %g", buffer, res);             else                 printf("%s == %gn", buffer, res);         }           if (buffer!=NULL)             free(buffer);     }       if (file != stdin)         fclose(file);       return 0; }

Добавлено через 5 часов 29 минут
Это вроде не утечка памяти
но где я использую память которую оссвободил не найти=(

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь

0

153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

19.04.2014, 13:55

2

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

Это вроде не утечка памяти

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

1

61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

20.04.2014, 12:27

 [ТС]

3

Вованя, не совсем понял как пройтись ?

Добавлено через 20 часов 49 минут
Помогите пожалуйста может я чего то не понимаю но как найти этот segfault?

0

153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

20.04.2014, 12:39

4

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

не совсем понял как пройтись ?

В какой IDE работаете?

0

61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

20.04.2014, 12:40

 [ТС]

5

Вованя, visual studio 2013

0

153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

20.04.2014, 12:46

6

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

visual studio 2013

Честно говоря, я с VS не очень дружу, но если не изменяет память, то просто жмите F5 и исполняйте программу, по идее ошибка должна перехватиться и указать на строку в коде.

0

61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

20.04.2014, 12:47

 [ТС]

7

Вованя, так в том то и дело что все нормально работает
А ошибка возникает при нехватке памяти при malloce что я не могу смоделировать

0

153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

20.04.2014, 13:00

8

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

все нормально работает

А что в вашем хедере?

0

61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

20.04.2014, 13:03

 [ТС]

9

Вованя, где ?
Калькулятор все высчитывает нормально пока не возникает нехватка памяти
Тогда то эта ошибка и возникает

Проверяю не я поэтому то и не могу понять где ошибка

0

153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

20.04.2014, 13:15

10

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

где ?

В calculator.h чего там лежит?

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

Калькулятор все высчитывает нормально пока не возникает нехватка памяти

Так на каком этапе то это происходит? В какой строчке то? Добавьте отладочной печати хотя бы уж, посмотрите, чего да как.

0

61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

20.04.2014, 13:20

 [ТС]

11

Вованя, возникает все в функции getstring так как выделение памяти происходит только там
А если бы я знал в какой строчке и почему я бы тут не задавал вопрос

0

153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

20.04.2014, 13:32

12

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

так как выделение памяти происходит только там

Ну вы бы могли перед каждым выделением памяти поместить функцию printf с текстом о строке и перед какой функцией этот printf вызывается и после каждого вызова malloc тоже поместить такой же printf с текстом, чтобы убедиться, где ошибок нет.

0

61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

20.04.2014, 13:44

 [ТС]

13

Вованя, так а смысл этого
Я смоделировать нехватку памяти не могу
Ее моделирует робот который проверяет программу
Соответственно он и присылает мне по почте ошибку которую возвращает моя программа
Даже если ядобавлю printf робот мне этого не скажет

Без нехватки памяти все работает нормально о чем робот и говорит
Только при нехватке памяти

0

153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

20.04.2014, 13:57

14

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

Только при нехватке памяти

Честно говоря, сразу так и не понятно было, что именно вас беспокоит
Ну на самом деле теперь стало еще запутанней. Не понятно, что вы хотите с этим сделать, в смысле, ну понятно, что если mallocrealloc не сможет выделить запрашиваемую память, то он вернет NULL, что, как я понимаю, и происходить при realloc. Тогда в таком случае и получается SEGFAULT, так как идет попытка записать в нулевой указатель. Ну тогда с этим ничего не поделать, это скорее не баг, а аппаратноесистемной ограничение.

0

61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

21.04.2014, 10:37

 [ТС]

15

Вованя, робот при проверке возвращает ошибку
Я хочу узнать из за чего она и как исправить чтобы программа прошла проверку

Добавлено через 5 часов 30 минут
Ну блин неужели нет решения этой проблемы?

Добавлено через 14 часов 34 минуты
Апнуз

0

5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

21.04.2014, 11:57

16

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

Я смоделировать нехватку памяти не могу

Кто мешает вместо сравнения на NULL сделать присвоение?

1

kiff20072008

61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

21.04.2014, 17:50

 [ТС]

17

alsav22,
смоделировал так

Кликните здесь для просмотра всего текста

C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 
#include <stdio.h> #include <string.h> #include <stdlib.h>     #include "conio.h" #include "error.h"     int getstring(FILE *file, char **buffer) {     int n = 1;     int c;     int i = 0;       if (feof(file))         return 1;     *buffer = NULL;     if (*buffer  == NULL)     {         if ((c = fgetc(file)) == EOF)             return 1;         if (c == 'n')         {             SetError(no_memory);             return 0;         }         while (((c = fgetc(file)) != EOF) && (c != 'n'));         SetError(no_memory);         return 0;     }     while ((c = fgetc(file)) != 'n')     {         if (c == EOF)             break;         if (c > 255 || c < 0)         {             printf("ERROR: wrong simbol");             return 0;         }         if (i >= (SIZE_ALLOC_MEMORY*n - 1))         {             char * temp;             ++n;             if ((temp = (char*) realloc(*buffer, SIZE_ALLOC_MEMORY*n*sizeof(char))) == NULL)             {                 while (((c = fgetc(file)) != EOF) && (c != 'n'));                 SetError(no_memory);                 return 0;             }             *buffer = temp;         }         (*buffer)[i] = (char) c;         ++i;     }     if (i != (SIZE_ALLOC_MEMORY*n))         (*buffer)[i] = '';     return 0; }

все проверки какие могу представить проходит

0

5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

22.04.2014, 04:13

18

Полный код дайте, чтобы проверить можно было в работе.

Добавлено через 1 час 46 минут

Цитата
Сообщение от alsav22
Посмотреть сообщение

Кто мешает вместо сравнения на NULL сделать присвоение?

Код (из первого поста), если там, где выделяется память, заменить сравнение с NULL на присваивание NULL, нормально отрабатывает?

0

kiff20072008

61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

22.04.2014, 09:15

 [ТС]

19

alsav22,
сделал чтобы рандомно память выделялась или не выделялась
и все нормально=(

C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 
#include <stdio.h> #include <string.h> #include <stdlib.h>     #include "conio.h" #include "error.h"   void mmaloc(char  **buffer,int n) {     int i = rand() % 4;     if (i == 1)         *buffer = NULL;     else         *buffer = (char*) malloc(SIZE_ALLOC_MEMORY * sizeof(char) *n);   }   void rrealoc(char  **buffer,char **temp, int n) {     int i = rand() % 4;     if (i == 1)         *temp = NULL;     else         *temp = (char*) realloc(*buffer, SIZE_ALLOC_MEMORY*n*sizeof(char));   }             int getstring(FILE *file, char **buffer) {     int n = 1;     int c;     int i = 0;       if (feof(file))         return 1;     mmaloc(buffer,n);     if ( *buffer== NULL)     {         if ((c = fgetc(file)) == EOF)             return 1;         if (c == 'n')         {             SetError(no_memory);             return 0;         }         while (((c = fgetc(file)) != EOF) && (c != 'n'));         SetError(no_memory);         return 0;     }     while ((c = fgetc(file)) != 'n')     {         if (c == EOF)             break;         if (c > 255 || c < 0)         {             printf("ERROR: wrong simbol");             return 0;         }         if (i >= (SIZE_ALLOC_MEMORY*n - 1))         {             char * temp;             ++n;             rrealoc(buffer,&temp, n);             if (temp  == NULL)             {                 while (((c = fgetc(file)) != EOF) && (c != 'n'));                 SetError(no_memory);                 return 0;             }             *buffer = temp;         }         (*buffer)[i] = (char) c;         ++i;     }     if (i != (SIZE_ALLOC_MEMORY*n))         (*buffer)[i] = '';     return 0; }

0

char name; 

Reserves just one byte for the name, so when you enter the name it creates a buffer overflow that produce a memory violation error.
Use a char array instead:

#include <stdio.h> #include <stdlib.h> int main() { printf("HI whats your name? "); char name[256]; //Note we are reserving space for up to 255 chars, //because the 256th must be reserved for the ending null. scanf("%s",name); //Note also that we don't use the & because an array is already a pointer printf("So your name is %s ", name); return 0; } 

A buffer overflow is a process where you try to stuff in a buffer more items than its size can contain. In your case you start to store the name characters in the location of the variable name and continue storing in the following memory cells eventually overwriting the variables that follows it.

Moreover, because the variable name is an automatic variable, it resides on the stack. When you store the input character will overwrite also the return address, that in most systems is saved on the same stack, with the result that when returning from the function the processor jumps to a wrong address.

When opportunely crafted a buffer overflow can voluntarily change the return address to force processor to execute malicius code. The so called «buffer overflow exploit».

char name; 

Reserves just one byte for the name, so when you enter the name it creates a buffer overflow that produce a memory violation error.
Use a char array instead:

#include <stdio.h> #include <stdlib.h> int main() { printf("HI whats your name? "); char name[256]; //Note we are reserving space for up to 255 chars, //because the 256th must be reserved for the ending null. scanf("%s",name); //Note also that we don't use the & because an array is already a pointer printf("So your name is %s ", name); return 0; } 

A buffer overflow is a process where you try to stuff in a buffer more items than its size can contain. In your case you start to store the name characters in the location of the variable name and continue storing in the following memory cells eventually overwriting the variables that follows it.

Moreover, because the variable name is an automatic variable, it resides on the stack. When you store the input character will overwrite also the return address, that in most systems is saved on the same stack, with the result that when returning from the function the processor jumps to a wrong address.

When opportunely crafted a buffer overflow can voluntarily change the return address to force processor to execute malicius code. The so called «buffer overflow exploit».

Почему программа завершается на S_object.findShortestWord(S_object.get(), str_value2); с Process returned -1073741819 (0xC0000005) execution time : 3.804 s?

#include <iostream> #include <stdio.h> #include <cstring> using namespace std; class FirstClass { public: char* str_value; public: FirstClass(const char* value = ""):str_value(0) { set(value); } FirstClass(const FirstClass &obj):str_value(0) { set(obj.str_value); }; ~FirstClass() {delete[] str_value;} void set(const char* value) { delete[] str_value; str_value = new char[strlen(value)+1]; strcpy(str_value, value); } const char* get() const { return str_value; } }; class SecondClass : public FirstClass { public: SecondClass(const char* str_value = "") : FirstClass (str_value) {} void findShortestWord(const char* in, char* out) { int len = strlen(in); int beginWord = 0; int lengthWord = 0; for (int i = 0; i < len; i++) { while ( (in[i] == ' ') && ( in[i] != '') ) i++; int begin = i; while ( (in[i] != ' ') && (in[i] != '') ) i++; int end = i; char tmp[256]; for(int j = begin, k=0; j < end; j++, k++) tmp[k] = in[j]; tmp[end - begin] = ''; int currentLen = end - begin; if (currentLen < lengthWord) { lengthWord = currentLen; beginWord = begin; } } for (int i = beginWord, k = 0; i < beginWord + lengthWord; i++, k++) out[k] = in[i]; out[lengthWord] = ''; } }; int main() { char* str_value2; FirstClass F_object("Hello my world 1"); printf("nFirstClass init: %s", F_object.get()); F_object.set("Hello my world 2"); printf("nFirstClass set: %s", F_object.get()); FirstClass F_object2 = F_object; SecondClass S_object(F_object.get()); printf("nSecondClass init: %s", S_object.get()); S_object.findShortestWord(S_object.get(), str_value2); //F_object = S_object; printf("nSearch and delete: %s", str_value2); return 0; } 

В операционной системе Windows, вне зависимости от версии, всегда имеются баги и ошибки, которые проявляются с разной частотой и интенсивностью. Одной из них является ошибка с кодом 1073741819, особенность которой заключается в невозможности инсталляции и запуска программ с правами администратора. Обычно она возникает после миграции с «семёрки» на более старшие версии, то есть пользователи Windows 10 встречаются с проблемой намного чаще. Но и в 7, и 8 Windows она тоже изредка встречается. Сегодня вы узнаете, что означает эта ошибка и как с ней бороться, не прибегая к посторонней помощи.

Ошибка файловой системы 1073741819

Сущность проблемы заключается в невозможности запуска исполняемых файлов с правами администратора. Из этого же следует, что вы не сможете установить на компьютер новый софт. При каждой попытке запуска программ с административными правами система контроля и администрирования учётных записей пользователей Windows (сокращённо – UAC) будет блокировать открытие этого файла с выдачей сообщения об ошибке 1073741819. По существу, будет также подавлена любая прочая административная активность с вашей стороны.

Основная причина выглядит довольно странно – это миграция с одной версии Windows на другую. В Microsoft допустили неточность, которая имеет столь тяжёлые последствия. Дело в том, что многие параметры пользователя из предыдущей версии ОС переносятся в новую операционку, в том числе и пользовательская звуковая схема. Но при этом некоторые системные звуки в «восьмерке» и «десятке» отсутствуют, что и приводит к блокировке административного доступа к различным системным сервисам и функциям со стороны UAC. Другими словами, ошибка в большинстве случаев проявляется после миграции, хотя известны и более экзотические причины.

Мы попытаемся рассмотреть все известные на сегодня способы решения данной проблемы.

Как устранить ошибку файловой системы 1073741819 в Windows 10/8/7

Исходя из того, что данный баг появляется из-за несоответствия звуковых схем и проявляется в основном при переходе с младшей версии Windows на старшую, а также что ошибка связана с блокировкой UAC прав администратора, мы и будем описывать способы решения проблемы.

Изменение звуковой схемы системы на значение «по умолчанию»

Самый очевидный способ устранения ошибки 1073741819 заключается в исправлении «неправильной» звуковой схемы. При этом у вас есть два варианта – использовать дефолтную схему, то есть схему для данной версии Windows «по умолчанию». Второй вариант не столь хорош – использование схемы «без звуков», но как временное решение его тоже можно использовать – хотя бы для того, чтобы убедиться, что дело именно в схеме. И если не в ней, то выполнить возврат к своим предпочтениям.

Итак, приводим последовательность действий:

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

Данный способ самый простой и эффективный, но он вряд ли устроит всех. Если вы привыкли к собственной звуковой схеме и не хотите её потерять, или если работа операционной системы без звуковых оповещений вас абсолютно не устраивает, следует отказаться от этого способа и использовать другие из перечисленных ниже.

Изменение рабочей темы Windows

Вы спросите, какое отношение имеет выбор темы в «десятке» к появлению ошибки 1073741819, связанной с файловой системой? Нельзя сказать, что самое непосредственное, но опосредованное – точно. Дело в том, что рабочая тема – это не только обои, но и заставка, цветовая и звуковая схема.

Переход к настройкам персонализации

Принцип решения проблемы предельно прост: вы выбираете любую тему из раздела «Темы по умолчанию», что автоматически приведёт к использованию дефолтной звуковой схемы.

Переход во вкладку «Темы»

Для выполнения этой операции нужно щёлкнуть ПКМ по пустому пространству на рабочем столе, а в появившемся контекстном меню выбрать пункт «Персонализировать». Откроется новое окно, где и следует выбрать тему по умолчанию, не обязательно называющуюся Windows 10.

Изменение темы Windows

Но, опять же, это вариант не для тех, кому дорога собственная звуковая схема, и таких пользователей, судя по всему, немало. Для них будет интересным решением следующий вариант.

Отключение UAC

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

Сам алгоритм следующий:

В принципе никто не мешает вам создать свою звуковую схему заново, чтобы не подвергать риску свой компьютер. Но если вы полагаетесь на то, что с любыми угрозами справится установленный антивирус, то такой вариант вполне достоин внимания.

Создание нового пользовательского аккаунта

Этот способ из той же серии – создавая учётную запись нового пользователя, вы автоматически делаете её беспроблемной, поскольку она не перенеслась из предыдущей версии Windows, а была создана в соответствии с текущими правилами.

Вкладка «Учётные записи»

Пункт «Семья и другие пользователи»

Старую учётную запись можно не удалять. Но нужно понимать, что если вы зайдёте в старый пользовательский аккаунт, ошибка 1073741819 снова будет вас сопровождать повсюду, где требуются действия с правами администратора.

Элемент «Добавить пользователя для этого компьютера»

Ссылка «У меня нет данных для входа этого человека»

Метод не слишком удобен и рационален, но если все вышеперечисленные варианты не сработали или являются для вас неприемлемыми – отчего ж не попробовать? При этом вы и решаете проблему, и не теряете свои предпочтения. Правда, пользоваться ими можно будет с определёнными ограничениями.

Пункт «Получить новый адрес электронной почты»

Создание учётной записи

Удаление подозрительного софта

Нельзя исключить и того, что ответственным за блокировку запуска файлов является отнюдь не UAC, особенно если вы убедились, что звуковая схема здесь ни при чём. Вполне может оказаться, что установленный ранее софт каким-то образом блокирует добавление новых файлов, тем самым препятствуя установке новых программ. Проверить, так ли это, можно с помощью антивируса. Не помешает и изучить особенности используемых приложений в поисковике. Возможно, от какой-то программы придётся отказаться.

Изменение параметров питания

А вот это уже действительно экзотика. Но, говорят, способ помогает, если другие не срабатывают.

Алгоритм действий следующий:

Удаление антивируса Avast

Иногда за блокировку запуска исполняемых файлов с правами администратора ответственен антивирус Avast, но вы не знаете, по какой причине он это делает. Лучший способ удостовериться, что виноват именно антивирус – отключить его. И если окажется, что ошибка 1073741819 – это его вина, лучше удалить Avast и заменить его другим антивирусным пакетом, благо выбор достаточно велик.

Удаление антивируса Avast

Восстановление системы

Ничто из перечисленного не помогло? Что ж, если исключить переустановку операционной системы, то в вашем распоряжении имеется более щадящий и очень действенный рецепт – это откат системы до состояния, когда ошибка с кодом 1073741819 вам не досаждала.

Восстановление системных файлов и параметров

Как это сделать, мы рассказывали не единожды, важно только понимать, каковы возможные последствия этого шага.

Заключение

В большинстве случаев решить проблему с ошибкой 1073741819 удаётся использованием дефолтной звуковой схемы или теми способами, которые косвенно приводят к такому же результату. Если ошибка начала проявляться неожиданно и не после перехода на старшую версию Windows, придётся основательно поработать, чтобы диагностировать «болезнь» и вылечить компьютер. Надеемся, что наша статья поможет вам в этом благородном деле.

Некоторые пользователи операционной системы Windows при запуске какого-либо приложения с правами администратора могут столкнуться с ошибкой «Ошибка файловой системы 1073741819». Довольно часто это происходит при переходе и соответствующем обновлении с Windows 7 на Windows 10, но бывают случаи, что с данной проблемой встречаются пользователями Windows 7 и Windows 8. В этой статье я расскажу, в чём суть ошибки данной дисфункции каковы её причины, и как исправить ошибку файловой системы на ваших ПК.

Скриншот Error code: - 1073741819

Содержание

  1. Причины ошибки
  2. Как исправить ошибку файловой системы 1073741819
  3. Способ 1. Измените звуковую схему на «по умолчанию»
  4. Способ 2. Измените рабочую тему ОС Windows
  5. Способ 3. Отключите UAC
  6. Способ 4. Создайте другой пользовательский аккаунт
  7. Способ 5.  Измените параметры питания
  8. Способ 6. Удалите AVAST
  9. Заключение

Причины ошибки

Наиболее часто с данной ошибкой встречаются пользователи ОС Виндовс 10, после перехода на неё с Виндовс 7. Возникновение данной ошибки не только мешает запуску программ с административными правами, но и просто не даёт установить в системе какой-либо новый софт. Каждый раз, когда пользователь пытается выполнить подобное, UAC (система контроля учётных записей пользователя) выдаёт ошибку 1073741819, по сути блокируя  административную активность в операционной системе.

Основной причиной, как не странно, обычно является звуковая схема, которая перешла с вашей Windows 7 на Windows 10 при обновлении из одной ОС в другую. По определённым причина Виндовс 10 не способна проигрывать некоторые системные звуки звуковой схемы Виндовс 7, и, как результат, UAC блокирует административный доступ к системному функционалу.

Иллюстрация доступ заблокирован

Как исправить ошибку файловой системы 1073741819

В соответствии с вышеописанным, пресловутая ошибка исправляется следующими способами:

Способ 1. Измените звуковую схему на «по умолчанию»

Для этого перейдите в «Панель Управления» – «Звуки», найдите там параметр «Звуковую схема» и установите на «По умолчанию» (или «Windows по умолчанию»). Рассматриваемая мной ошибка после этого должна пропасть.

Скрин настроек звука в Windows

Выберите звуковую схему «По умолчанию»

Рекомендую также отключить уведомления UAC, для чего откройте стартовое меню, найдите и кликните на «Контроль учётных записей пользователя» (User Access Control), нажмите на «Изменение параметров контроля учётной записи» (Change User Access Control»), и установите ползунок в самое нижнее значение.

Способ 2. Измените рабочую тему ОС Windows

  1. Также в решении ошибки 1073741819 может помочь изменение темы рабочего стола.
  2. Наведите курсор на свободное место рабочего стола, кликните правой клавишей мыши и выберите «Персонализация».
  3. В настройках персонализации кликаем на «Темы», и там  выбираем тему «Виндовс 10».

Способ 3. Отключите UAC

  1. Перейдите в стартовое меню, выберите там Панель управления, поищите UAC, кликните на «Изменение параметров контроля учётной записи» (Change User Access Control).
  2. Установите ползунок в самое нижнее значение (никогда не уведомлять).
  3. После выполнения этого нажмите на кнопку «Spacebar» (пробел), и прощёлкайте системные сообщения, которые могут после этого появиться.
  4. Это может помочь решить ошибку 1073741819 в Виндовс 7 и 10.

Иллюстрация настройки уведомлений

Способ 4. Создайте другой пользовательский аккаунт

Ещё одним, и довольно эффективным способом решения проблемы 1073741819, будет создание новой учётной записи и работа с ней. Обычно в новой «учётке» рассматриваемая мной проблема пропадает.

Способ 5.  Измените параметры питания

  1. Переходим в «Панель Управления» — «Система и безопасность» —  «Электропитание», выбираем настройки текущей схемы управления питания (обычно это «Сбалансированная»).
  2. Жмём там на  «Изменить дополнительные параметры питания», устанавливаем параметр от сети и батареи в «Оптимальное энергосбережение».

Способ 6. Удалите AVAST

В довольно редких случаях причиной рассматриваемой проблемы выступал функционал антивируса AVAST, установленного на компьютере пользователя. Для избавления от ошибки 1073741819 рекомендуется полностью удалить данный антивирус с вашего компьютера, заменив его более стабильной альтернативой.

Заключение

Основным решением проблемы «Ошибка файловой системы 1073741819» является схема звуковой схемы, использующейся по умолчанию в ОС Windows. Если данный вариант не помог, попробуйте другие, перечисленные мной, советы, они помогут устранить ошибку 1073741819 на ваших ПК.

Опубликовано 31 марта 2017 Обновлено 30 сентября 2020

7 способов исправления ошибки файловой системы 1073741819 в ОС Windows 10

После обновления операционной системы Виндовс 10 или перехода с ранней версии пользователь при открытии файла с правами Администратора может столкнуться с ошибкой 1073741819. Чаще неполадка возникает с файлами формата .exe и связана с аудиодрайверами и звуковой схемой на ПК. По какой причине возникает ошибка файловой системы 1073741819 в компьютере с Windows 10 и как от нее избавиться, читаем далее.

Виды ошибок файловой системы и основные причины их возникновения

При физически исправном устройстве файловая система может давать сбой. В этом случае юзеру закрыт доступ к некоторым файлам или утилитам. Система указывает на проблемный объект и пишет код соответствующей ошибки, который обозначает причинно-следственную связь.

screenshot_1

Практика показывает, что владельцам гаджетов чаще всего приходится сталкиваться со следующими кодами:

  • 2147219195 – причиной появления распространенной ошибки становятся действия по оптимизации Винды либо проблемы с приложением «Фотографии»;
  • 1073740791 – возникает в случае сбоя сектора в месте записи проблемного приложения или после внезапного отключения ПК;
  • 805305975 – появляется при просмотре изображений, причиной служат программные проблемы, возникшие из-за повреждения файлов системы;
  • 12007 – возникает после прерывания загрузки или неполной установки ПО, при повреждении реестра Виндовса, вирусных атаках;
  • Nvidia – причинами возникновения служат: перегрузка видеокарты, баги в ранее установленных обновлениях ОС, битые сектора на диске;
  • 2018374635 – сбой вызывается драйвером видеокарты;
  • 1073741189 – ошибка связана с работой контроля учетных записей пользователя (UAC);
  • 1073741515 – возникает из-за ошибок реестра в ОС, отсутствия необходимых компонентов для запуска файла;
  • 1073741792 – причинами появления ошибки становятся неверно выставленные системные настройки или нерегулярные записи в реестре Винды.

Все описываемые ошибки носят определенный характер, возникают по разным причинам. Несмотря на это, варианты исправления неполадок предполагают стандартный набор возможных решений.

screenshot_2

Как исправить ошибки?

Устранить описываемые неполадки пользователь может самостоятельно, выбрав оптимальный для своего устройства вариант. Рекомендуется предварительно создать точку восстановления, которая может понадобиться в случае непредвиденных ситуаций.

Восстановление системы

Если возникновение неполадки с кодом 1073741819 связано с системными изменениями, которые были внесены вручную пользователем или установленными утилитами, тогда исправить ситуацию поможет восстановление системы. Для возврата в первоначальный вид Винды нужно выполнить следующее:

  • Войти в меню «Параметры» через кнопку «Пуск».

screenshot_3

  • Выбрать «Обновление и безопасность».

screenshot_4

  • В левой части меню найти «Восстановление», кликнуть один раз ЛКМ.
  • Тапнуть по кнопке «Начать».

screenshot_5

  • Выбрать один из предложенных вариантов восстановления с сохранением или удалением данных.

screenshot_6

  • Начнется подготовка к процессу, нажать «Далее».

screenshot_7

  • Появится список последствий, нажать кнопку «Сброс».

screenshot_8

  • Дождаться окончания процесса.

Во время восстановления системы компьютер будет несколько раз перезагружаться. На экране юзер увидит прогресс процедуры. В результате Виндовс представит отчет о проделанной работе.

Проверка диска

Нестабильная работа HDD может стать причиной появления описываемой ошибки. Исправить ситуацию можно, воспользовавшись встроенными средствами или скачанными утилитами. Проверить диск на наличие ошибок при помощи штатных программ можно следующим способом:

  • Войти в «Этот компьютер».
  • Выбрать соответствующий раздел, кликнуть по нему ПКМ.
  • Выбрать из списка «Свойства».

screenshot_9

  • Перейти во вкладку «Сервис».
  • Щелкнуть по кнопке «Проверить».

screenshot_10

  • Нажать на «Проверить диск».

screenshot_11

  • Дождаться завершения процесса.

После окончания сканирования система выявит и исправит неполадки. Работа раздела будет восстановлена.

Проверка системных файлов

Причин повреждения файлов системы может быть множество. Проверить их целостность в Windows 10 поможет встроенное средство – Командная строка. Для запуска утилиты нужно выполнить следующее:

  • Открыть меню «Пуск».
  • В поисковой строке набрать: «cmd».
  • Кликнуть по КС с правами Администратора.

screenshot_12

  • В открывшемся меню ввести команду: «sfc/scannow».

screenshot_13

  • Дождаться окончания процесса верификации файлов.

В результате пользователь увидит сообщение об обнаружении проблемных файлов, которые будут заменены корректными версиями.

Создание новой учетной записи пользователя

Такой вариант исправления ошибки с кодом 1073741819 поможет избежать переустановки Винды. Для этого достаточно создать новую учетку. Самый быстрый способ создания нового аккаунта – с помощью Командной строки:

  • Открыть «Пуск».
  • Ввести в поисковую строку: «cmd».

screenshot_14

  • Ввести команду: «net user «Имя пользователя» /add», где Имя пользователя – название новой учетной записи.

screenshot_15

  • Нажать клавишу ввода.

Пользователю останется переместить данные в новый профиль, а старый удалить.

Сброс кэша хранилища Windows

Простой способ, который подразумевает всего три простых действия:

  • Нажать на клавиатуре комбинацию клавиш: «Win + R».
  • Ввести в строку команду: «Wsreset.exe».

screenshot_16

  • Нажать «Enter».

После завершения процедуры нужно перезапустить систему на ПК.

Изменение звуковой схемы вашего ПК

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

  • Нажать на Панели задач на значок динамика.
  • Из списка выбрать строку «Звуки».

screenshot_17

  • Изменить значение на вариант «Без звука» или «По умолчанию».

screenshot_18

  • Нажать «Ok».

Чтобы изменения вступили в силу, пользователю нужно перезагрузить компьютер. Ошибки файловой системы должны исчезнуть.

Другие способы решения

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

Возможной причиной появления сообщения с кодом 1073741819 может стать тема оформления. Многим пользователям смена темы оформления помогает устранить подобного рода проблему. Для выполнения операции достаточно войти в «Персонализацию» ПК, выбрать пункт «Темы по умолчанию». После сохранения настроек юзеру нужно снова попробовать запустить проблемный файл.

screenshot_19

Ошибка файловой системы 1073741819 в Windows 10 исправляется разными способами, описанными выше. Если юзеру так и не удалось выявить причину неполадки, в крайнем случае, поможет сброс системы до заводских настроек.

Содержание

  • Способ 1: Запуск установщика от имени администратора
  • Способ 2: Изменение параметров контроля учетных записей
  • Способ 3: Установка стандартной звуковой схемы
  • Способ 4: Удаление подозрительного софта
  • Способ 5: Сканирование ПК на наличие вирусов
  • Способ 6: Проверка целостности системных файлов
  • Способ 7: Восстановление ОС
  • Вопросы и ответы

Ошибка файловой системы 1073741819 в Windows 7

Способ 1: Запуск установщика от имени администратора

Если при попытке установить программу в Windows 7 появилась ошибка файловой системы с кодом 1073741819, попробуйте выполнить самое простое решение — запустить инсталлятор от имени администратора. Во многих случаях это исправляет проблемы с доступом к файлам и позволяет установке начаться корректно.

Запуск программы от имени администратора для решения ошибки файловой системы 1073741819 в Windows 7

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

Подробнее: Как получить права администратора в Windows 7

Предоставление прав администратора для решения ошибки файловой системы 1073741819 в Windows 7

Способ 2: Изменение параметров контроля учетных записей

Еще одна причина, по которой возникают ошибки с установкой разных программ. По умолчанию в Windows 7 установлены параметры контроля учетных записей, уведомляющие администратора о внесении любых изменений в систему, что касается и инсталляции софта. Если отключить подобные уведомления, проблема с файловой системой должна исчезнуть.

  1. Для этого перейдите в «Панель управления» через меню «Пуск».
  2. Переход в Панель управления для решения ошибки файловой системы 1073741819 в Windows 7

  3. Найдите и откройте раздел «Центр поддержки».
  4. Переход в настройки поддержки для решения ошибки файловой системы 1073741819 в Windows 7

  5. В нем переключитесь в «Изменение параметров контроля учетных записей», для которого тоже понадобятся права администратора. Об их получении мы рассказывали в предыдущем способе.
  6. Открытие настроек контроля учетных записей для решения ошибки 1073741819 в Windows 7

  7. Переместите ползунок уведомлений в состояние «Никогда не уведомлять», а затем подтвердите внесение изменений.
  8. Смена настроек контроля учетных записей для решения ошибки 1073741819 в Windows 7

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

Способ 3: Установка стандартной звуковой схемы

В большинстве случаев этот способ актуален для обладателей Windows 10, поскольку там неправильно перенесенные звуковые схемы из Виндовс 7 сказываются на установке софта, ведь запуск инсталлятора сопровождается системными звуками. Однако на всякий случай мы советуем проверить этот параметр и обладателям «семерки», чтобы исключить данную причину.

  1. В том же окне «Панели управления» перейдите в меню «Звук».
  2. Переход в настройки используемой звуковой схемы для решения ошибки 1073741819 в Windows 7

  3. На вкладке «Звуки» выберите звуковую схему по умолчанию, открыв соответствующее выпадающее меню.
  4. Выбор стандартной звуковой схемы для решения ошибки файловой системы 1073741819 в Windows 7

    Lumpics.ru

Способ 4: Удаление подозрительного софта

Выше мы разобрались с методами, ориентированными конкретно под ошибку файловой системы 1073741819. Если ни один из них не принес должного результата, самое время заняться выполнением общих рекомендаций по отладке работы операционной системы. Начните с проверки подозрительного софта, который может быть установлен в ОС. Некоторые программы влияют на установку других, блокируя добавление новых файлов, поэтому советуем избавиться от ненужных и подозрительных приложений. Вводите их названия в поисковике, если сомневаетесь, нужна ли конкретная программа на компьютере.

Подробнее: Инсталляция и деинсталляция программ в Windows 7

Удаление ненужных и подозрительных программ для решения ошибки файловой системы 1073741819 в Windows 7

Способ 5: Сканирование ПК на наличие вирусов

Заражение компьютера вирусами — частая проблема, сопровождающаяся различными неполадками операционной системы, в том числе и теми, которые могут появляться при инсталляции софта. Благо обнаружить угрозу на компьютере не так сложно, потому что можно воспользоваться специальными антивирусными программами. Об их выборе и использовании читайте в другой статье на нашем сайте.

Подробнее: Борьба с компьютерными вирусами

Проверка компьютера на наличие вирусов для решения ошибки файловой системы 1073741819 в Windows 7

Способ 6: Проверка целостности системных файлов

За установку других приложений в Windows 7 отвечают системные файлы. Если какие-либо из них были повреждены или отсутствуют, появляются разные ошибки, мешающие инсталляции. Проверить целостность таких файлов можно при помощи встроенных в операционную систему утилит, запускающихся через «Командную строку». О том, как правильно производить такое сканирование, рассказывает другой наш автор в материале далее.

Подробнее: Проверка целостности системных файлов Windows 7

Сканирование целостности системных файлов для решения ошибки файловой системы 1073741819 в Windows 7

Это самый радикальный метод, переходить к которому следует в тех случаях, когда ничего из перечисленного выше не принесло должного результата. Вы можете вернуть состояние операционной системы к тому моменту, когда ошибка 1073741819 еще не появлялась, либо же полностью сбросить все настройки. Выбирайте метод в зависимости от того, создавали ли вы резервные копии и производилась ли ручная настройка восстановления.

Подробнее: Как восстановить Windows 7

Восстановление операционной системы для решения ошибки файловой системы 1073741819 в Windows 7

Я пытаюсь создать дерево AVL и вставить в него узел. Всякий раз, когда я пытаюсь добавить значение данных в узел дерева, моя программа аварийно завершает работу и возвращает значение 0xC0000005. Вот как я ввел элемент данных в заголовочный файл:

class AVLTreeNode { public: int data; AVLTreeNode(); virtual ~AVLTreeNode(); AVLTreeNode(int d, AVLTreeNode *leftChild, AVLTreeNode *rightChild); AVLTreeNode *leftc; AVLTreeNode *rightc; int height; } 

Всякий раз, когда я пытаюсь запустить следующие строки кода в функции вставки, я получаю сбой.

AVLTreeNode *nw = NULL ; nw->data = v; 

Я не знаю, что я делаю не так, пожалуйста, помогите мне.

-3

Решение

Значит код возврата 0xC0000005 STATUS_ACCESS_VIOLATION, (Вы можете найти этот и другие коды состояния NT на MSDN: NTSTATUS ценности.) Ошибка происходит из-за NULL находится вне диапазона допустимых адресов для вашей программы. Перед разыменованием переменной указателя вы должны присвоить ей адрес допустимого объекта. Например:

AVLTreeNode* nw = new AVLTreeNode{}; nw->data = v; 

0

Другие решения

AVLTreeNode *nw = NULL; 

Эта строка кодовых наборов nw быть нулевым указателем, другими словами, он ни на что не указывает. Попытка разыменования нулевого указателя приведет к неопределенному поведению. Вы должны выделить память для AVLTreeNode объект, а затем получить nw указать на это.

Вместо этого вам нужно то, что выделяет память и очки nw на него:

AVLTreeNode *nw = new AVLTreeNode; 

И помните, всякий раз, когда вы выделяете память new вам нужно освободить его, когда вы закончите с этим:

delete nw; 

-1

Сообщение Кратко Сообщается ли номер теста? Значение вердикта Возможная причина
OK OK Нет Решение зачтено Программа верно работает на соответствующем наборе тестов
Compilation error CE Нет Компиляция программы завершилась с ошибкой 1. в программе допущена синтаксическая или семантическая ошибка 2. неправильно указан язык
Wrong answer WA Да Ответ неверен 1. ошибка в программе 2. неверный алгоритм
Presentation error PE Да Тестирующая система не может проверить выходные данные, так как их формат не соответствует описанному в условиях задачи 1. неверный формат вывода 2. программа не печатает результат 3. лишний вывод
Time-limit exceeded TL Да Программа превысила установленный лимит времени 1. ошибка в программе 2. неэффективное решение
Memory limit exceeded ML Да Программа превысила установленный в условиях лимит памяти 1. ошибка в программе (например, бесконечная рекурсия) 2. неэффективное решение
Output limit exceeded OL Да Программа превысила установленный в условиях лимит вывода 1. программа выводит больше информации, чем установлено в ограничениях
Run-time error RE Да Программа завершила работу с ненулевым кодом возврата 1. ошибка выполнения 2. программа на C или C++ не завершается оператором return 0 3. ненулевой код возврата указан явно 4. Программа на Java описана в пакете
Precompile check failed PCF Нет Программа не прошла проверку на качество кода перед компиляцией 1. плохое качество кода 2. неправильно отформатированный код
Idleness limit exceeded IL Да Программа слишком долго не отвечала на запросы системы и не выполняла действий 1. программа ожидает ввода с консоли, которого не должно быть 2. не использован flush()

У меня проблема с cocos2d-x 3.6, я установил программу и создал свой первый файл hello world, найденный в программе, но при попытке запустить я получаю следующую ошибку, кто-нибудь может подсказать как исправить и объяснить почему это случилось ошибка

cocos run -s ~/MyCompany2/MyGame -p linux

Запуск команды: скомпилировать

Режим сборки: отладка

работает: ‘cmake -DCMAKE_BUILD_TYPE=Debug -DDEBUG_MODE=ON ..’

— Идентификация компилятора C: GNU 4.9.2.

— Компилятор CXX идентифицируется как GNU 4.9.2.

— Проверить работоспособность компилятора C: / usr / bin / cc

— Проверить работоспособность компилятора C: /usr/bin/cc — работает

— Обнаружение информации ABI компилятора C

— Обнаружение информации ABI компилятора C — выполнено

— Обнаружение особенностей компиляции C

— Обнаружение особенностей компиляции C — готово

— Проверить работоспособность компилятора CXX: /usr/bin/g++

— Проверить работоспособность компилятора CXX: /usr/bin/g++ — работает

— Обнаружение информации ABI компилятора CXX

— Обнаружение информации ABI компилятора CXX — выполнено

— Обнаружение функций компиляции CXX

— Обнаружение функций компиляции CXX — готово

Похоже, вы изначально собираете Linux с помощью GCC.

— Включаемые каталоги OpenGL: /usr/include

— GLEW включает каталоги: /usr/include

— PkgConfig найден

— проверка модуля ‘glfw3’

— пакет ‘glfw3’ не найден

Ошибка CMake в cocos2d/cmake/Modules/FindPackageHandleStandardArgs.cmake:136 (сообщение):

НЕ удалось найти GLFW3 (отсутствует: GLFW3_LIBRARIES GLFW3_INCLUDE_DIR)

Стек вызовов (сначала последний вызов):

cocos2d/cmake/Modules/FindPackageHandleStandardArgs.cmake:343

(_FPHSA_FAILURE_MESSAGE)

cocos2d/cmake/Модули/FindGLFW3.cmake:152

(find_package_handle_standard_args)

cocos2d/cmake/Modules/CocosBuildHelpers.cmake:44 (find_package)

cocos2d/CMakeLists.txt:187 (cocos_find_package)

— Конфигурирование неполное, произошли ошибки!

См. также «/home/jmuniz/MyCompany2/MyGame/linux-build/CMakeFile/CMakeOutput.log».

Ошибка выполнения команды, код возврата: 1

В C++ различают ошибки времени компиляции и ошибки времени выполнения. Ошибки первого типа обнаруживает компилятор до запуска программы. К ним относятся, например, синтаксические ошибки в коде. Ошибки второго типа проявляются при запуске программы. Примеры ошибок времени выполнения: ввод некорректных данных, некорректная работа с памятью, недостаток места на диске и т. д. Часто такие ошибки могут привести к неопределённому поведению программы.

Некоторые ошибки времени выполнения можно обнаружить заранее с помощью проверок в коде. Например, такими могут быть ошибки, нарушающие инвариант класса в конструкторе. Обычно, если ошибка обнаружена, то дальнейшее выполение функции не имеет смысла, и нужно сообщить об ошибке в то место кода, откуда эта функция была вызвана. Для этого предназначен механизм исключений.

Коды возврата и исключения

Рассмотрим функцию, которая считывает со стандартного потока возраст и возвращает его вызывающей стороне. Добавим в функцию проверку корректности возраста: он должен находиться в диапазоне от 0 до 128 лет. Предположим, что повторный ввод возраста в случае ошибки не предусмотрен.

int ReadAge() {
    int age;
    std::cin >> age;
    if (age < 0 || age >= 128) {
        // Что вернуть в этом случае?
    }
    return age;
}

Что вернуть в случае некорректного возраста? Можно было бы, например, договориться, что в этом случае функция возвращает ноль. Но тогда похожая проверка должна быть и в месте вызова функции:

int main() {
    if (int age = ReadAge(); age == 0) {
        // Произошла ошибка
    } else {
        // Работаем с возрастом age
    }
}

Такая проверка неудобна. Более того, нет никакой гарантии, что в вызывающей функции программист вообще её напишет. Фактически мы тут выбрали некоторое значение функции (ноль), обозначающее ошибку. Это пример подхода к обработке ошибок через коды возврата. Другим примером такого подхода является хорошо знакомая нам функция main. Только она должна возвращать ноль при успешном завершении и что-либо ненулевое в случае ошибки.

Другим способом сообщить об обнаруженной ошибке являются исключения. С каждым сгенерированным исключением связан некоторый объект, который как-то описывает ошибку. Таким объектом может быть что угодно — даже целое число или строка. Но обычно для описания ошибки заводят специальный класс и генерируют объект этого класса:

#include <iostream>

struct WrongAgeException {
    int age;
};

int ReadAge() {
    int age;
    std::cin >> age;
    if (age < 0 || age >= 128) {
        throw WrongAgeException(age);
    }
    return age;
}

Здесь в случае ошибки оператор throw генерирует исключение, которое представлено временным объектом типа WrongAgeException. В этом объекте сохранён для контекста текущий неправильный возраст age. Функция досрочно завершает работу: у неё нет возможности обработать эту ошибку, и она должна сообщить о ней наружу. Поток управления возвращается в то место, откуда функция была вызвана. Там исключение может быть перехвачено и обработано.

Перехват исключения

Мы вызывали нашу функцию ReadAge из функции main. Обработать ошибку в месте вызова можно с помощью блока try/catch:

int main() {
    try {
        age = ReadAge();  // может сгенерировать исключение
        // Работаем с возрастом age
    } catch (const WrongAgeException& ex) {  // ловим объект исключения
        std::cerr << "Age is not correct: " << ex.age << "n";
        return 1;  // выходим из функции main с ненулевым кодом возврата
    }
    // ...
}

Мы знаем заранее, что функция ReadAge может сгенерировать исключение типа WrongAgeException. Поэтому мы оборачиваем вызов этой функции в блок try. Если происходит исключение, для него подбирается подходящий catch-обработчик. Таких обработчиков может быть несколько. Можно смотреть на них как на набор перегруженных функций от одного аргумента — объекта исключения. Выбирается первый подходящий по типу обработчик и выполняется его код. Если же ни один обработчик не подходит по типу, то исключение считается необработанным. В этом случае оно пробрасывается дальше по стеку — туда, откуда была вызвана текущая функция. А если обработчик не найдётся даже в функции main, то программа аварийно завершается.

Усложним немного наш пример, чтобы из функции ReadAge могли вылетать исключения разных типов. Сейчас мы проверяем только значение возраста, считая, что на вход поступило число. Но предположим, что поток ввода досрочно оборвался, или на входе была строка вместо числа. В таком случае конструкция std::cin >> age никак не изменит переменную age, а лишь возведёт специальный флаг ошибки в объекте std::cin. Наша переменная age останется непроинициализированной: в ней будет лежать неопределённый мусор. Можно было бы явно проверить этот флаг в объекте std::cin, но мы вместо этого включим режим генерации исключений при таких ошибках ввода:

int ReadAge() {
    std::cin.exceptions(std::istream::failbit);
    int age;
    std::cin >> age;
    if (age < 0 || age >= 128) {
        throw WrongAgeException(age);
    }
    return age;
}

Теперь ошибка чтения в операторе >> у потока ввода будет приводить к исключению типа std::istream::failure. Функция ReadAge его не обрабатывает. Поэтому такое исключение покинет пределы этой функции. Поймаем его в функции main:

int main() {
    try {
        age = ReadAge();  // может сгенерировать исключения разных типов
        // Работаем с возрастом age
    } catch (const WrongAgeException& ex) {
        std::cerr << "Age is not correct: " << ex.age << "n";
        return 1;
    } catch (const std::istream::failure& ex) {
        std::cerr << "Failed to read age: " << ex.what() << "n";
        return 1;
    } catch (...) {
        std::cerr << "Some other exceptionn";
        return 1;
    }
    // ...
}

При обработке мы воспользовались функцией ex.what у исключения типа std::istream::failure. Такие функции есть у всех исключений стандартной библиотеки: они возвращают текстовое описание ошибки.

Обратите внимание на третий catch с многоточием. Такой блок, если он присутствует, будет перехватывать любые исключения, не перехваченные ранее.

Исключения стандартной библиотеки

Функции и классы стандартной библиотеки в некоторых ситуациях генерируют исключения особых типов. Все такие типы выстроены в иерархию наследования от базового класса std::exception. Иерархия классов позволяет писать обработчик catch сразу на группу ошибок, которые представлены базовым классом: std::logic_error, std::runtime_error и т. д.

Вот несколько примеров:

  1. Функция at у контейнеров std::array, std::vector и std::deque генерирует исключение std::out_of_range при некорректном индексе.

  2. Аналогично, функция at у std::map, std::unordered_map и у соответствующих мультиконтейнеров генерирует исключение std::out_of_range при отсутствующем ключе.

  3. Обращение к значению у пустого объекта std::optional приводит к исключению std::bad_optional_access.

  4. Потоки ввода-вывода могут генерировать исключение std::ios_base::failure.

Исключения в конструкторах

В главе 3.1 мы написали класс Time. Этот класс должен был соблюдать инвариант на значение часов, минут и секунд: они должны были быть корректными. Если на вход конструктору класса Time передавались некорректные значения, мы приводили их к корректным, используя деление с остатком.

Более правильным было бы сгенерировать в конструкторе исключение. Таким образом мы бы явно передали сообщение об ошибке во внешнюю функцию, которая пыталась создать объект.

class Time {
private:
    int hours, minutes, seconds;

public:
    // Заведём класс для исключения и поместим его внутрь класса Time как в пространство имён
    class IncorrectTimeException {
    };

    Time::Time(int h, int m, int s) {
        if (s < 0 || s > 59 || m < 0 || m > 59 || h < 0 || h > 23) {
            throw IncorrectTimeException();
        }
        hours = h;
        minutes = m;
        seconds = s;
    }

    // ...
};

Генерировать исключения в конструкторах — совершенно нормальная практика. Однако не следует допускать, чтобы исключения покидали пределы деструкторов. Чтобы понять причины, посмотрим подробнее, что происходит при генерации исключения.

Свёртка стека

Вспомним класс Logger из предыдущей главы. Посмотрим, как он ведёт себя при возникновении исключения. Воспользуемся в этом примере стандартным базовым классом std::exception, чтобы не писать свой класс исключения.

#include <exception>
#include <iostream>

void f() {
    std::cout << "Welcome to f()!n";
    Logger x;
    // ...
    throw std::exception();  // в какой-то момент происходит исключение
}

int main() {
    try {
        Logger y;
        f();
    } catch (const std::exception&) {
        std::cout << "Something happened...n";
        return 1;
    }
}

Мы увидим такой вывод:

Logger(): 1
Welcome to f()!
Logger(): 2
~Logger(): 2
~Logger(): 1
Something happened...

Сначала создаётся объект y в блоке try. Затем мы входим в функцию f. В ней создаётся объект x. После этого происходит исключение. Мы должны досрочно покинуть функцию. В этот момент начинается свёртка стека (stack unwinding): вызываются деструкторы для всех созданных объектов в самой функции и в блоке try, как если бы они вышли из своей области видимости. Поэтому перед обработчиком исключения мы видим вызов деструктора объекта x, а затем — объекта y.

Аналогично, свёртка стека происходит и при генерации исключения в конструкторе. Напишем класс с полем Logger и сгенерируем нарочно исключение в его конструкторе:

#include <exception>
#include <iostream>

class C {
private:
    Logger x;

public:
    C() {
        std::cout << "C()n";
        Logger y;
        // ...
        throw std::exception();
    }

    ~C() {
        std::cout << "~C()n";
    }
};

int main() {
    try {
        C c;
    } catch (const std::exception&) {
        std::cout << "Something happened...n";
    }
}

Вывод программы:

Logger(): 1  // конструктор поля x
C()
Logger(): 2  // конструктор локальной переменной y
~Logger(): 2  // свёртка стека: деструктор y
~Logger(): 1  // свёртка стека: деструктор поля x
Something happened...

Заметим, что деструктор самого класса C не вызывается, так как объект в конструкторе не был создан.

Механизм свёртки стека гарантирует, что деструкторы для всех созданных автоматических объектов или полей класса в любом случае будут вызваны. Однако он полагается на важное свойство: деструкторы самих классов не должны генерировать исключений. Если исключение в деструкторе произойдёт в момент свёртки стека при обработке другого исключения, то программа аварийно завершится.

Пример с динамической памятью

Подчеркнём, что свёртка стека работает только с автоматическими объектами. В этом нет ничего удивительного: ведь за временем жизни объектов, созданных в динамической памяти, программист должен следить самостоятельно. Исключения вносят дополнительные сложности в ручное управление динамическими объектами:

void f() {
    Logger* ptr = new Logger();  // конструируем объект класса Logger в динамической памяти
    // ...
    g();  // вызываем какую-то функцию
    // ...
    delete ptr;  // вызываем деструктор и очищаем динамическую память
}

На первый взгляд кажется, что в этом коде нет ничего опасного: delete вызывается в конце функции. Однако функция g может сгенерировать исключение. Мы не перехватываем его в нашей функции f. Механизм свёртки уберёт со стека лишь сам указатель ptr, который является автоматической переменной примитивного типа. Однако он ничего не сможет сделать с объектом в памяти, на которую ссылается этот указатель. В логе мы увидим только вызов конструктора класса Logger, но не увидим вызова деструктора. Нам придётся обработать исключение вручную:

void f() {
    Logger* ptr = new Logger();
    // ...
    try {
        g();
    } catch (...) {  // ловим любое исключение
        delete ptr;  // вручную удаляем объект
        throw;  // перекидываем объект исключения дальше
    }
    // ...
    delete ptr;

}

Здесь мы перехватываем любое исключение и частично обрабатываем его, удаляя объект в динамической памяти. Затем мы прокидываем текущий объект исключения дальше с помощью оператора throw без аргументов.

Согласитесь, этот код очень далёк от совершенства. При непосредственной работе с объектами в динамической памяти нам приходится оборачивать в try/catch любую конструкцию, из которой может вылететь исключение. Понятно, что такой код чреват ошибками. В главе 3.6 мы узнаем, как с точки зрения C++ следует работать с такими ресурсами, как память.

Гарантии безопасности исключений

Предположим, что мы пишем свой класс-контейнер, похожий на двусвязный список. Наш контейнер позволяет добавлять элементы в хранилище и отдельно хранит количество элементов в некотором поле elementsCount. Один из инвариантов этого класса такой: значение elementsCount равно реальному числу элементов в хранилище.

Не вдаваясь в детали, давайте посмотрим, как могла бы выглядеть функция добавления элемента.

template <typename T>
class List {
private:
    struct Node {  // узел двусвязного списка
        T element;
        Node* prev = nullptr;  // предыдущий узел
        Node* next = nullptr;  // следующий узел
    };

    Node* first = nullptr;  // первый узел списка
    Node* last = nullptr;  // последний узел списка
    int elementsCount = 0;

public:
    // ...

    size_t Size() const {
        return elementsCount;
    }

    void PushBack(const T& elem) {
        ++elementsCount;

        // Конструируем в динамической памяти новой узел списка
        Node* node = new Node(elem, last, nullptr);

        // Связываем новый узел с остальными узлами
        if (last != nullptr) {
            last->next = node;
        } else {
            first = node;
        }
        last = node;
    }
};

Не будем здесь рассматривать другие функции класса — конструкторы, деструктор, оператор присваивания… Рассмотрим функцию PushBack. В ней могут произойти такие исключения:

  1. Выражение new может сгенерировать исключение std::bad_alloc из-за нехватки памяти.

  2. Конструктор копирования класса T может сгенерировать произвольное исключение. Этот конструктор вызывается при инициализации поля element создаваемого узла в конструкторе класса Node. В этом случае new ведёт себя как транзакция: выделенная перед этим динамическая память корректно вернётся системе.

Эти исключения не перехватываются в функции PushBack. Их может перехватить код, из которого PushBack вызывался:

#include <iostream>

class C;  // какой-то класс

int main() {
    List<C> data;
    C element;

    try {
        data.PushBack(element);
    } catch (...) {  // не получилось добавить элемент
        std::cout << data.Size() << "n";  // внезапно 1, а не 0
    }

    // работаем дальше с data
}

Наша функция PushBack сначала увеличивает счётчик элементов, а затем выполняет опасные операции. Если происходит исключение, то в классе List нарушается инвариант: значение счётчика elementsCount перестаёт соответствовать реальности. Можно сказать, что функция PushBack не даёт гарантий безопасности.

Всего выделяют четыре уровня гарантий безопасности исключений (exception safety guarantees):

  1. Гарантия отсутствия сбоев. Функции с такими гарантиями вообще не выбрасывают исключений. Примерами могут служить правильно написанные деструктор и конструктор перемещения, а также константные функции вида Size.

  2. Строгая гарантия безопасности. Исключение может возникнуть, но от этого объект нашего класса не поменяет состояние: количество элементов останется прежним, итераторы и ссылки не будут инвалидированы и т. д.

  3. Базовая гарантия безопасности. При исключении состояние объекта может поменяться, но оно останется внутренне согласованным, то есть, инварианты будут соблюдаться.

  4. Отсутсвие гарантий. Это довольно опасная категория: при возникновении исключений могут нарушаться инварианты.

Всегда стоит разрабатывать классы, обеспечивающие хотя бы базовую гарантию безопасности. При этом не всегда возможно эффективно обеспечить строгую гарантию.

Переместим в нашей функции PushBack изменение счётчика в конец:

    void PushBack(const T& elem) {
        Node* node = new Node(elem, last, nullptr);

        if (last != nullptr) {
            last->next = node;
        } else {
            first = node;
        }
        last = node;

        ++elementsCount;  // выполнится только если раньше не было исключений
    }

Теперь такая функция соответствует строгой гарантии безопасности.

В документации функций из классов стандартной библиотеки обычно указано, какой уровень гарантии они обеспечивают. Рассмотрим, например, гарантии безопасности класса std::vector.

  • Деструктор, функции empty, size, capacity, а также clear предоставляют гарантию отсутствия сбоев.

  • Функции push_back и resize предоставляют строгую гарантию.

  • Функция insert предоставляет лишь базовую гарантию. Можно было бы сделать так, чтобы она предоставляла строгую гарантию, но за это пришлось бы заплатить её эффективностью: при вставке в середину вектора пришлось бы делать реаллокацию.

Функции класса, которые гарантируют отсутсвие сбоев, следует помечать ключевым словом noexcept:

class C {
public:
    void f() noexcept {
        // ...
    }
};

С одной стороны, эта подсказка позволяет компилятору генерировать более эффективный код. С другой — эффективно обрабатывать объекты таких классов в стандартных контейнерах. Например, std::vector<C> при реаллокации будет использовать конструктор перемещения класса C, если он помечен как noexcept. В противном случае будет использован конструктор копирования, который может быть менее эффективен, но зато позволит обеспечить строгую гарантию безопасности при реаллокации.

kiff20072008

61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

1

19.04.2014, 00:14. Показов 21882. Ответов 18

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Есть программа калькулятор
и в ней в случае нехватки памяти выводится соответствующая ошибка
однако проверяющий сказал мне что у меня нарушение доступа к памяти
смоделировать нехватку я не могу
анализируя код найти где у меня это нарушение не могу

Кликните здесь для просмотра всего текста

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
 
 
#include "calculator.h"
 
 
 
int getstring(FILE *file, char **buffer)
{
    int n = 1, c = EOF, i = 0;
    if (feof(file))
        return 1;
    if ((*buffer = (char*) malloc(SIZE_ALLOC_MEMORY * sizeof(char) *n)) == NULL)
    {
        if ((c = fgetc(file)) == EOF)
            return 1;
        if (c == 'n')
        {
            SetError(no_memory);
            return 0;
        }
        while (((c = fgetc(file)) != 'n') && (c!=EOF) )
        {
            ;
        }
        SetError(no_memory);
        return 0;
    }
    while ((c = fgetc(file)) != 'n')
    {
        if (c == EOF)
            break;
        if (c > 255 || c < 0)
        {
            printf("ERROR: wrong simbol");
            return 0;
        }
        if (i >= (SIZE_ALLOC_MEMORY * n - 1))
        {
            char *temp;
 
            n++;
            if ((temp = (char *) realloc(*buffer, sizeof(char) * SIZE_ALLOC_MEMORY * n)) == NULL)
            {
                while (((c = fgetc(file)) != 'n') && (c != EOF) )
                {
                    ;
                }
                SetError(no_memory);
                return 0;
            }
            *buffer = temp;
        }
        (*buffer)[i] = (char) c;
        i++;
    }
    if (i <= (SIZE_ALLOC_MEMORY * n - 1))
        (*buffer)[i] = 0;
    return 0;
}
 
int main(int Argc, char *Argv[])
{
    FILE *file=stdin;
    char *buffer = NULL;
    char *bufferPtr;
 
 
 
 
    if (Argc == 2)
    {
        fopen_s(&file, Argv[1], "rt");
 
        if (file == NULL)
        {
            printf("nERROR:NO FILE");
            return 1;
        }
    }
    if (Argc > 2)
    {
        printf("nERROR: TOO MUCH ARGUMENTS");
        return 1;
    }
    while (!getstring(file, &buffer))
    {
 
        if (IsError())
        {
            if (feof(file))
                printf("ERROR: %s",  GetLastErrorDescription());
            else
                printf("ERROR: %sn", GetLastErrorDescription());
            SetError(No_error);
            if (buffer != NULL)
                free(buffer);
            continue;
        }
         bufferPtr = buffer;
 
        while (IS_SPACE(*bufferPtr)) 
            bufferPtr++;
        if (*bufferPtr == 0 || (bufferPtr[0] == '/' && bufferPtr[1] == '/'))
        {
            if (feof(file))
                printf("%s", buffer);
            else
                printf("%sn", buffer);
        }
        else
        {
            double res;
            res = Calculator(bufferPtr);
            ClearVarTable();
            if (IsError())
            {
            if (feof(file))
                printf("%s == ERROR: %s", buffer, GetLastErrorDescription());
            else
                printf("%s == ERROR: %sn", buffer, GetLastErrorDescription());
            SetError(No_error);
            }
            else
            if (feof(file))
                printf("%s == %g", buffer, res);
            else
                printf("%s == %gn", buffer, res);
        }
 
        if (buffer!=NULL)
            free(buffer);
    }
 
    if (file != stdin)
        fclose(file);
 
    return 0;
}

Добавлено через 5 часов 29 минут
Это вроде не утечка памяти
но где я использую память которую оссвободил не найти=(



0



153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

19.04.2014, 13:55

2

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

Это вроде не утечка памяти

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



1



61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

20.04.2014, 12:27

 [ТС]

3

Вованя, не совсем понял как пройтись ?

Добавлено через 20 часов 49 минут
Помогите пожалуйста может я чего то не понимаю но как найти этот segfault?



0



153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

20.04.2014, 12:39

4

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

не совсем понял как пройтись ?

В какой IDE работаете?



0



61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

20.04.2014, 12:40

 [ТС]

5

Вованя, visual studio 2013



0



153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

20.04.2014, 12:46

6

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

visual studio 2013

Честно говоря, я с VS не очень дружу, но если не изменяет память, то просто жмите F5 и исполняйте программу, по идее ошибка должна перехватиться и указать на строку в коде.



0



61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

20.04.2014, 12:47

 [ТС]

7

Вованя, так в том то и дело что все нормально работает
А ошибка возникает при нехватке памяти при malloce что я не могу смоделировать



0



153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

20.04.2014, 13:00

8

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

все нормально работает

А что в вашем хедере?



0



61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

20.04.2014, 13:03

 [ТС]

9

Вованя, где ?
Калькулятор все высчитывает нормально пока не возникает нехватка памяти
Тогда то эта ошибка и возникает

Проверяю не я поэтому то и не могу понять где ошибка



0



153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

20.04.2014, 13:15

10

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

где ?

В calculator.h чего там лежит?

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

Калькулятор все высчитывает нормально пока не возникает нехватка памяти

Так на каком этапе то это происходит? В какой строчке то? Добавьте отладочной печати хотя бы уж, посмотрите, чего да как.



0



61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

20.04.2014, 13:20

 [ТС]

11

Вованя, возникает все в функции getstring так как выделение памяти происходит только там
А если бы я знал в какой строчке и почему я бы тут не задавал вопрос



0



153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

20.04.2014, 13:32

12

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

так как выделение памяти происходит только там

Ну вы бы могли перед каждым выделением памяти поместить функцию printf с текстом о строке и перед какой функцией этот printf вызывается и после каждого вызова malloc тоже поместить такой же printf с текстом, чтобы убедиться, где ошибок нет.



0



61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

20.04.2014, 13:44

 [ТС]

13

Вованя, так а смысл этого
Я смоделировать нехватку памяти не могу
Ее моделирует робот который проверяет программу
Соответственно он и присылает мне по почте ошибку которую возвращает моя программа
Даже если ядобавлю printf робот мне этого не скажет

Без нехватки памяти все работает нормально о чем робот и говорит
Только при нехватке памяти



0



153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

20.04.2014, 13:57

14

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

Только при нехватке памяти

Честно говоря, сразу так и не понятно было, что именно вас беспокоит
Ну на самом деле теперь стало еще запутанней. Не понятно, что вы хотите с этим сделать, в смысле, ну понятно, что если mallocrealloc не сможет выделить запрашиваемую память, то он вернет NULL, что, как я понимаю, и происходить при realloc. Тогда в таком случае и получается SEGFAULT, так как идет попытка записать в нулевой указатель. Ну тогда с этим ничего не поделать, это скорее не баг, а аппаратноесистемной ограничение.



0



61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

21.04.2014, 10:37

 [ТС]

15

Вованя, робот при проверке возвращает ошибку
Я хочу узнать из за чего она и как исправить чтобы программа прошла проверку

Добавлено через 5 часов 30 минут
Ну блин неужели нет решения этой проблемы?

Добавлено через 14 часов 34 минуты
Апнуз



0



5496 / 4891 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

21.04.2014, 11:57

16

Цитата
Сообщение от kiff20072008
Посмотреть сообщение

Я смоделировать нехватку памяти не могу

Кто мешает вместо сравнения на NULL сделать присвоение?



1



kiff20072008

61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

21.04.2014, 17:50

 [ТС]

17

alsav22,
смоделировал так

Кликните здесь для просмотра всего текста

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
 
#include "conio.h"
#include "error.h"
 
 
int getstring(FILE *file, char **buffer)
{
    int n = 1;
    int c;
    int i = 0;
 
    if (feof(file))
        return 1;
    *buffer = NULL;
    if (*buffer  == NULL)
    {
        if ((c = fgetc(file)) == EOF)
            return 1;
        if (c == 'n')
        {
            SetError(no_memory);
            return 0;
        }
        while (((c = fgetc(file)) != EOF) && (c != 'n'));
        SetError(no_memory);
        return 0;
    }
    while ((c = fgetc(file)) != 'n')
    {
        if (c == EOF)
            break;
        if (c > 255 || c < 0)
        {
            printf("ERROR: wrong simbol");
            return 0;
        }
        if (i >= (SIZE_ALLOC_MEMORY*n - 1))
        {
            char * temp;
            ++n;
            if ((temp = (char*) realloc(*buffer, SIZE_ALLOC_MEMORY*n*sizeof(char))) == NULL)
            {
                while (((c = fgetc(file)) != EOF) && (c != 'n'));
                SetError(no_memory);
                return 0;
            }
            *buffer = temp;
        }
        (*buffer)[i] = (char) c;
        ++i;
    }
    if (i != (SIZE_ALLOC_MEMORY*n))
        (*buffer)[i] = '';
    return 0;
}

все проверки какие могу представить проходит



0



5496 / 4891 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

22.04.2014, 04:13

18

Полный код дайте, чтобы проверить можно было в работе.

Добавлено через 1 час 46 минут

Цитата
Сообщение от alsav22
Посмотреть сообщение

Кто мешает вместо сравнения на NULL сделать присвоение?

Код (из первого поста), если там, где выделяется память, заменить сравнение с NULL на присваивание NULL, нормально отрабатывает?



0



kiff20072008

61 / 61 / 24

Регистрация: 28.09.2012

Сообщений: 378

22.04.2014, 09:15

 [ТС]

19

alsav22,
сделал чтобы рандомно память выделялась или не выделялась
и все нормально=(

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
 
#include "conio.h"
#include "error.h"
 
void mmaloc(char  **buffer,int n)
{
    int i = rand() % 4;
    if (i == 1)
        *buffer = NULL;
    else
        *buffer = (char*) malloc(SIZE_ALLOC_MEMORY * sizeof(char) *n);
 
}
 
void rrealoc(char  **buffer,char **temp, int n)
{
    int i = rand() % 4;
    if (i == 1)
        *temp = NULL;
    else
        *temp = (char*) realloc(*buffer, SIZE_ALLOC_MEMORY*n*sizeof(char));
 
}
 
 
 
 
 
 
int getstring(FILE *file, char **buffer)
{
    int n = 1;
    int c;
    int i = 0;
 
    if (feof(file))
        return 1;
    mmaloc(buffer,n);
    if ( *buffer== NULL)
    {
        if ((c = fgetc(file)) == EOF)
            return 1;
        if (c == 'n')
        {
            SetError(no_memory);
            return 0;
        }
        while (((c = fgetc(file)) != EOF) && (c != 'n'));
        SetError(no_memory);
        return 0;
    }
    while ((c = fgetc(file)) != 'n')
    {
        if (c == EOF)
            break;
        if (c > 255 || c < 0)
        {
            printf("ERROR: wrong simbol");
            return 0;
        }
        if (i >= (SIZE_ALLOC_MEMORY*n - 1))
        {
            char * temp;
            ++n;
            rrealoc(buffer,&temp, n);
            if (temp  == NULL)
            {
                while (((c = fgetc(file)) != EOF) && (c != 'n'));
                SetError(no_memory);
                return 0;
            }
            *buffer = temp;
        }
        (*buffer)[i] = (char) c;
        ++i;
    }
    if (i != (SIZE_ALLOC_MEMORY*n))
        (*buffer)[i] = '';
    return 0;
}



0



Понравилась статья? Поделить с друзьями:
  • Ошибка исполнения запроса от сервера получено сообщение сбербанк
  • Ошибка исполнения запроса drive2
  • Ошибка искомая страница не существует faceit
  • Ошибка исключительной блокировки информационной базы что это
  • Ошибка исключительной блокировки информационной базы фоновое задание