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

Не понимаю один момент, который заключается в следующем: мне необходимо получить данные из двоичного файла (.bin), куда раннее были записаны данные в виде двух строчек string и двух чисел int (структуры, в общем), при исполнении кода:

void Opf() {
	if ((fl = fopen(flName, "rb")) == NULL) {
		cout << "Ошибка открытия файла..." << endl;
		exit(1);
	}
	nst = 0;
	TBook book;
	while (true)
	{
		int nwrt = fread(&book, sizeof(TBook), 1, fl);
		if (nwrt != 1) { break; }
		books[nst] = book;
		cout << books[nst].name << " " << " " << books[nst].author << " " 
			<< books[nst].yearof << " " << books[nst].pages << endl;
		nst++;
	}
	fclose(fl);
}

Выдаёт следующую ошибку:

Вызвано необработанное исключение: нарушение доступа для чтения.
**_Pnext** было 0x61747353.

В чём может быть ошибка или же как можно это обойти?

Задача: По данным n отрезкам необходимо найти множество точек минимального размера, для которого каждый из отрезков содержит хотя бы одну из точек.

В первой строке дано число 1≤n≤100 отрезков. Каждая из последующих n строк содержит по два числа 0≤l≤r≤109, задающих начало и конец отрезка. Выведите оптимальное число m точек и сами m точек. Если таких множеств точек несколько, выведите любое из них.

Мое решение:

void swap(int *a1, int *a2, int M);
void sort(int **a, int N, int M);
void greedy(int **a, int *x, int N);

int main()
{
int **a;//двумерный массив отрезков
int N;
int M=2;
int *x;//одномерный массив точек

cout << "Enter N: "; //ввод количества отрезков
cin>>N;

x = new int[N]; //инициализация массива, который потом станет массивом точек
for (int i=0; i<N; i++)
    x[i]=0;

a = new int *[N];
for (int i = 0; i < N; i++)
    a[i] = new int [M];
//ввод концов отрезков    
for (int i = 0; i < N; i++)
{
    for (int j = 0; j < M; j++)
    {
        cin >> a[i][j];
    }
}
//вывод до сортировки
cout <<endl << "Before sorting:" << endl;

for (int i = 0; i < N; i++)
{
    for (int j = 0; j < M; j++)
        cout << std::setw(3) << a[i][j] << " ";
        cout << endl;
}


sort(a, N, M);//сортировка массива

//вывод после сортировки
cout << endl << "After sorting:" << endl;

for (int i = 0; i < N; i++)
{
    for (int j = 0; j < M; j++)
        cout << setw(3) << a[i][j] << " ";

    cout << endl;
}
//вызов функции с жадным алгоритмом
greedy(a,x, N);

for (int i=0; i<=N; i++)
    cout<<x[i]<<' ';

system("pause");
return 0;
}


void swap(int *a1, int *a2, int M)//меняет 2 строки местами
{
for (int i = 0; i < M; i++)
{
    int temp = a1[i];
    a1[i] = a2[i];
    a2[i] = temp;
    }
}

void sort(int **a, int N, int M)//сортировка пузырьком отрезков по правой   точке 
{
for (int i = 0; i < N; i++)
    for (int j = N - 1; j > i; j--)
        if (a[j - 1][1] >a[j][1])
            swap(a[j - 1], a[j], M);
}

void greedy(int **a, int *x,  int N)
{
int i=0;
int k=0;
while (i<=N)
{
    x[k]=a[i][1];
    i++;
    while ((x[k]>=a[i][0]) && (x[k]<=a[i][1]))
    {i++;}
    k++;
}

}

Но программа падает с ошибкой: Нарушение прав доступа при чтении. Может, кто видит, почему?

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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
#include <iostream>
#include <ctime>
//#include <stdio.h>
using namespace std;
struct Node
{
    int key;
    struct Node* next;
    struct Node* prev;
};
class List
{
private:
    int key = 0;
    size_t size = 0;
    Node* head = NULL;
    Node* tail = NULL;
public:
    List()
    {
        head = tail;
        size;
        cout << "List is created!" << endl;
    }
    List (int a)
    {
        int elementov{}, N{}, K{}, tmpHand[100] = {}, tmpRand{};
        if (a == 2)
            Rand();
 
        if (a == 1)
            Hand();
            
        cout << "Elements are created!" << endl;
    }
    ~List()
    {
        Node* current = head;
        while (current != 0) {
            Node* next = current->next;
            delete current;
            current = next;
        }
        head = 0;
        cout << "Destructor deleted list!" << endl;
    }
    
    
    Node* Get_node(int number);
    Node* Create_node(int key);
    void Insert(const int key);
    void Print();
    void Pop_front();
    void Swap(Node* const before1, Node* const before2);
    void Append(const int num);
    int Get_Value(int N);
    void Inverse_sublist(const int K, const int N);
    void Hand();
    void Rand();
};
 
 
// получение адреса элемента по его порядковому номеру (счет от 1 )
Node* List::Get_node(int number)
{
    int i;
    Node* scan = this->head;
 
    if (scan == nullptr)
        return 0;
 
    for (i = 1; i < number; i++)
        scan = scan->next;
 
    return scan;
}
 
void List::Hand()
{
    int tmpHand[100]{}, elementov{};
     for (int i = elementov; i > 0; i--)
            {
                cout << "Введите элемент списка: n" << endl;
                cin >> tmpHand[i];
                Append(tmpHand[i]);
            }
}
 
void List::Rand()
{
    int tmpRand{}, elementov{};
    for (int i = 0; i < elementov; i++)
    {
        tmpRand = rand() % 100;
        Insert(tmpRand);
    }
}
 
Node* List::Create_node(int key)
{
    Node* new_node = (Node*)malloc(sizeof(Node));
    if (new_node) {
        new_node->key = key;
        new_node->next = NULL;
    }
        return new_node;
    
}
// вставка элемента в начало списка
void List::Insert(const int key)
{
    Node* add = Create_node(key);
    if (this->head != NULL)
        add->next = this->head;
    this->head = add;
    this->size++;
}
 
// вывод списка на экран
void List::Print()
{
    Node* scan = this->head;
    printf("List items: ");
    while (scan)
    {
        printf("%d -> %p ", scan->key, scan->next);
        scan = scan->next;
    }
}
 
// удаление элемента из начала ЛОС
void List::Pop_front()
{
    Node* del = this->head;
    this->head = del->next;
    free(del);
    this->size--;
}
 
// обмен местами двух элементов ЛОС
void List::Swap(Node* const before1, Node* const before2)
{
    Node* self1, * self2, * tmp;
    // before1 = Get_node(list, N1-1);
    // before2 = Get_node(list, N2-1);
    self1 = before1->next;
    self2 = before2->next;
    tmp = before1->next;
    before1->next = before2->next;
 
    before2->next = tmp;
    tmp = self1->next;
    self1->next = self2->next;
    self2->next = tmp;
 
}
 
void List::Append(const int num)
{
    Node* const add_node = Create_node(num);
    this->size++;
 
    // если список пуст
    if (!this->head)
    {
        this->head = this->tail = add_node;
    }
 
    this->tail->next = add_node;
    this->tail = add_node;
}
 
int List::Get_Value(int N)
{
    Node* tmp = Get_node(N);
    return tmp->key;
}
 
void List::Inverse_sublist(const int K, const int N)
{
    int i, j;
    Node* left = Get_node(K - 1);
    if (left == nullptr)
        return;
    Node* right;
    for (i = 0; i < N / 2; i++)
    {
        //right = left->next;//может быть сделать так?
        right = left;
        for (j = 0; j < (N - 2 * i) && right->next != nullptr; j++)
            right = right->next;
 
        Swap(left, right);
        left = left->next;
    }
}
 
//--------------------------------------------------------------
 
int main(int argc, char* argv[])
{
    //logo();
    printf("В списке целых ненулевых элементов инвертировать K элементов начиная с Nn");
    srand((unsigned int)time(NULL));
    int i = 0, tmpRand = 0;
    int tmpHand[100] = {};
    //ClassList::Node* node_a = 0;
    //ClassList::Node* node_b = 0;
 
    FILE* config;
    char Conf_Name[50] = "testo.cfg", buffer[100];
    int sposob{}, elementov{}, K{}, N{};
    if ((config = fopen(Conf_Name, "r")) == NULL) {
        puts("Config file error!!!");
        puts("Press Enter!!!");
        std::cin.get(); exit(0);
    }
 
    fgets(buffer, 80, config);
    if (!strstr(buffer, "#!MYCONFIG")) {
        puts("Config file error!!!");
        puts("Press Enter!!!");
        std::cin.get(); fclose(config);
        exit(0);
    }
 
    while (true)
    {
        fgets(buffer, 80, config);
        if (feof(config))break;
        if (buffer[0] == '#')continue;
        if (buffer[0] == '!') { puts(buffer); continue; }
        if (strstr(buffer, "sposob=")) {
            sposob = atoi(buffer + strlen("sposob="));
            continue;
        }
        if (strstr(buffer, "elementov=")) {
            elementov = atoi(buffer + strlen("elementov="));
            continue;
        }
        if (strstr(buffer, "K=")) {
            K = atoi(buffer + strlen("K="));
            continue;
        }
        if (strstr(buffer, "N=")) {
            N = atoi(buffer + strlen("N="));
            continue;
        }
 
    }
    puts("=============Result of parsing config file ========");
    cout << "sposob = " <<  sposob << endl;
    cout << "elementov = " <<  elementov << endl;
    cout  << "K = " <<  K << endl;
    cout << "N = " <<  N << endl;
    cout << "Press Enter!!!" << endl;
    std::cin.get(); fclose(config);
 
 
    if (elementov > 20)
    {
        printf("Слишком много элементов в списке! Выход...n");
        return 1;
    }
    if (sposob != 1 && sposob != 2)
    {
        printf("Некорректный способ заполнения спискаn");
        return 1;
    }
    if (K + N > elementov)
    {
        printf("Некорректные данные в конфигурационном файле (N + K > элементовn)");
        return 1;
    }
    if (N > elementov)
    {
        printf("Некорректные данные: количество инвертируемых элементов больше чем элементов в спискеn");
        return 1;
    }
 
 
    // "объект" ЛОС с инициализацией
    List list(sposob);
    list.Print();
    list.Inverse_sublist(K, N);
    list.Print();
 
}

I am currently working on the BlackJack project, but there is an error showing «exception Unhandled: Unhandled exception thrown: read access violation. this was 0x4.». I am not quite sure which part I did wrong, and the program sometimes runs normally sometimes shows that exception. In draw_card function, it returns a value of a random number. For example: if we get 13, the value will be 10. It also returns the name of the card and the type of the card such as 13 corresponds to king.

int main()
{
    srand(time(0));
    unsigned bet;
    int player = 0 , dealer = 0;
    string card , type;

    cout << "You have $100. Enter bet: ";
    cin >> bet;
    
    cout << "Your cards are:" << endl; 
    player += draw_card(card, type, player);
    cout << "  "+card + " of " + type << endl;
    player += draw_card(card, type, player);
    cout << "  " + card + " of " + type << endl << endl << endl;
}

int draw_card(string& card, string& type, int drawer_points) {
    int randomNumber;  //between 1 and 13
    int suite;         //between 1 and 4 to determine the suite of the card.

    randomNumber = rand() % 13 + 1;
    suite = rand() % 4 + 1;
    
    card = getRank(randomNumber);
    type = getSuit(suite);

    if (randomNumber == 13 || randomNumber == 12 || randomNumber == 11) {
        return 10;
    }else if (randomNumber == 1) {
        int ace1 = 21 - (drawer_points + 1);
        int ace2 = 21 - (drawer_points + 11);

        return ace1 < ace2 ? 1 : 11;
    }
    else
    {
        return randomNumber;
    }
}


string getSuit(int suit) {
    
    switch (suit)
    {
    case 0:
        return "spades";
        break;
    case 1:
        return "clubs";
        break;
    case 2:
        return "diamonds";
        break;
    case 3:
        return "hearts";
        break;
    default:
        break;
    }
    
}

string getRank(int rank) {
    switch (rank)
    {
    case 13:
        return "King";
        break;
    case 12:
        return "Queen";
        break;
    case 11:
        return "Jack";
        break;
    case 1:
        return "Ace";
        break;
    case 2:
        return "Two";
        break;
    case 3:
        return "Three";
        break;
    case 4:
        return "Four";
        break;
    case 5:
        return "Five";
        break;
    case 6:
        return "Six";
        break;
    case 7:
        return "Seven";
        break;
    case 8:
        return "Eight";
        break;
    case 9:
        return "Nine";
        break;
    case 10:
        return "Ten";
        break;
    default:
        break;
    }

user438383's user avatar

user438383

5,5868 gold badges28 silver badges41 bronze badges

asked Jan 18, 2022 at 18:12

Danny Zhao's user avatar

5

You generate

suite = rand() % 4 + 1;

This is a random number between 1 and 4 inclusive.

You then call

getSuit(suite);

But getSuit only has switch branches for values between 0 and 3 inclusive:

switch (suit)
{
case 0:
    return "spades";
    break;
case 1:
    return "clubs";
    break;
case 2:
    return "diamonds";
    break;
case 3:
    return "hearts";
    break;
default:
    break;
}

Not returning a value from a function that is declared to return a value is undefined behaviour.

answered Jan 18, 2022 at 18:27

konsolas's user avatar

konsolaskonsolas

1,00111 silver badges24 bronze badges

A few functions like getSuit and getRank in your code don’t return a value if only the default case of their switch statement is executed.

You can return an empty string in the default cases:

default:
        return ""; // empty string

And in the call site, check to see if the returned value is empty using the empty function.

Another way is to use std::optional<T> like below:

std::optional<string> getSuit( const int suit )
{
    switch (suit)
    {
    case 0:
        return "spades";
    case 1:
        return "clubs";
    case 2:
        return "diamonds";
    case 3:
        return "hearts";
    default:
        return { }; // empty optional
    }
}

And in the call site:

std::optinal<std::string> type { getSuit(suite) };

if ( type ) // if optional has value
{
    // extract and use the value inside of optional
    type.value( );
}

Keep in mind that if the optional does not have a value, using value() will throw. You can use value_or() instead which does not throw.

answered Jan 18, 2022 at 18:28

digito_evo's user avatar

digito_evodigito_evo

3,1542 gold badges13 silver badges39 bronze badges

2

#c #exception #visual-studio-2019

#c #исключение #visual-studio-2019

Вопрос:

Я не понимаю, что происходит.

Я создал программу для получения ввода символа и вывода его обратно. Я получаю это исключение каждый раз, когда нажимаю enter для ввода значения в программу:

Генерируется необработанное исключение: нарушение доступа для чтения. this->_format_it было 0x38.

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

Вот код:

 // Card Value
// cardValue.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
    char rank = 'c';

    printf("Enter the card rank : ");
    scanf("%c", amp;rank);
    printf(rank);

    return 0;
}
 

Удаление оператора адреса приведет к другому исключению:

Необработанное исключение в 0x79B498F1 (ucrtbased.dll ) в Карточке Decks.exe : 0xC0000005: местоположение записи с нарушением доступа 0x00000063.

Комментарии:

1. Какая перегрузка printf не требует ничего, кроме a char ? Можете ли вы указать нам на документацию для этого?

2. printf(rank); недопустимо, поскольку printf() не принимает ни одного char в качестве входных данных. 1-й параметр должен быть a char* , так что, возможно, вы на самом деле использовали printf(amp;rank); вместо этого? Это также было бы недопустимо, поскольку не является допустимой amp;rank строкой с нулевым завершением. Вместо этого вам нужно использовать printf("%c", rank); .

3. C в любом случае не поддерживает перегрузки.

4. …. или исключения.

5. Обратите внимание, что #define _CRT_SECURE_NO_WARNINGS это не подавляет то предупреждение, которое вы должны были видеть о переходе char printf .

Ответ №1:

printf() первым аргументом должен быть указатель на строку формата, а не символ. Вы могли бы сделать

 printf("%c", rank);
 

Комментарии:

1. Это дает мне совершенно другую ошибку.

2. Необработанное исключение в 0x79B498F1 (ucrtbased.dll ) в Карточке Decks.exe : 0xC0000005: местоположение записи с нарушением доступа 0x00000063.

3. @CarsonFujita-Тернбулл, потому что вы «удалили адрес оператора» без предупреждения и без какой-либо причины для этого

Ответ №2:

printf(rank); неверно, поскольку printf() не принимает ни одного char такого ввода.

В C этот код вообще не будет компилироваться. Но в C компилятор неявно преобразует целочисленное значение в указатель и char является целочисленным типом.

Ошибка нарушения доступа для чтения жалуется на считываемый адрес памяти 0x38 . 0x38 это код ASCII для символа '8' , это значение, которое вы вводите?

1-й параметр printf() должен быть char* указателем на строку формата с нулевым завершением, например:

 printf("%c", rank);
 

Все примеры в коде, который вам дал ваш колледж, представлены в этой аналогичной форме.


Если вы удалите amp; on scanf("%c", amp;rank) вызов (почему?), Вы получите запись с нарушением доступа к адресу памяти 0x63 , потому что значение rank неявно преобразуется как есть в указатель. 0x63 это код ASCII для символа 'c' , который вы инициализируете rank .

Комментарии:

1. Да, я идиот. Я заменил его на » printf («% c», rank); » и исправил это

Понравилась статья? Поделить с друзьями:
  • Ошибка наборщицы 8 букв
  • Ошибка наруто шипуден
  • Ошибка набора номера лимит исчерпан le eco
  • Ошибка наружного блока кондиционера lessar ed
  • Ошибка набора команды sms starline a93