Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Ash_Evil_Dead
0 / 0 / 0
Регистрация: 26.12.2015
Сообщений: 11
#1

Почему происходит выход за границы массива в функции Analyze()? - C++

15.02.2016, 19:07. Просмотров 348. Ответов 15

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
#include "Analyzer.h"
#include "HashTable.h"
#include <iostream>
#include <iomanip>
using namespace std;
 
 
Analyzer::Analyzer()
{
    kword[0] = "return";
    kword[1] = "for";
    kword[2] = "goto";
    kword[3] = "int";
 
    ksign[0] = '{';
    ksign[1] = '}';
    ksign[2] = '(';
    ksign[3] = ')';
    ksign[4] = ';';
    ksign[5] = ',';
    ksign[6] = '+';
    ksign[7] = '-';
    ksign[8] = '=';
    ksign[9] = '!';
    ksign[10] = '<';
    ksign[11] = '>';
 
    nline = 0;
    n = -1;
}
 
Analyzer::~Analyzer()
{
}
 
void Analyzer::InputData(ifstream& fin)
{
    while (fin.getline(buf, bufLength))
    {
        buffer += buf;
        buffer += "\n";
    }
}
 
void Analyzer::OutputData(ofstream& fout)
{
    fout << setw(0) << "Номер строки:";
    fout << setw(15) << "Код Типа:";
    fout << setw(19) << "Название Лексемы:";
    fout << setw(16) << "Лексема:";
    fout << setw(17) << "Хэш-Код:";
    fout << endl;
    for (int i = 0; i < n+1; i++)
    {
        h[i].Print(fout);
    }
}
 
int Analyzer::Hash(string lex)
{
    int hashCode = 0;
    for (int i = 0; i < lex.length(); i++)
    {
        hashCode += (int)lex[i];
    }
    hashCode %= 100;
    return hashCode;
}
 
void Analyzer::Analyze()
{
 
    nline = 1;
    for (int i = 0; i < buffer.length(); i++)
    {
        string lex;
        while ((buffer[i] != '\n') && (buffer[i] != ' '))
        {
            lex += buffer[i];
            i++;
        }
        Lexic(lex);
        if (buffer[i] == '\n')
            nline++;
        lex = "";
    }
}
 
void Analyzer::Lexic(string lex)
{
    int alpha = 0;
    int numbers = 0;
    int signs = 0;
    int flag = false;
    int id = 0;
    int type = -1;
    for (int i = 0; i < lex.length(); i++)
    {
        if (isalpha(lex[i]))
            alpha++;
        if (isdigit(lex[i]))
            numbers++;
        if (!isalpha(lex[i]) && (!isdigit(lex[i])) && (lex.length() == 1))
            signs++;
    }
    n++;
    while (flag == false)                   //Нахождение хэш кода
    {
        id = Hash(lex);
        for (int k = 0; k < n; k++)
        {
            if (h[k].Getid() == id)
            {
                id = Hash(lex) + rand() % 10 + 1;
                k = 0;
            }
        }
        flag = true;
    }
    if (alpha == lex.length() && (alpha != 0))
    {
        type = 1;
        for (int k = 0; k < 4; k++)
        {
            if (lex == kword[k])
                type = 0;
        }
        h[n].Create(nline, type, lex, id);
    }
    if (numbers == lex.length() && (numbers != 0))              //Число
    {
        h[n].Create(nline, 3, lex, id);
    }
    if ((signs == lex.length() && (signs != 0)))                //Cимвол
    {
        h[n].Create(nline, 2, lex, id);
    }
    if ((alpha != lex.length()) && (numbers != lex.length()) && (signs != lex.length()))    //Ошибка
        h[n].Create(nline, -1, lex, id);
}
,
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
#pragma once
#include "HashTable.h"
#include <iostream>
#include <string>
 
using namespace std;
 
class Analyzer
{
private:
    const int size = 100;
    const int lexemeAmount = 100;
    const int bufLength = 100;
 
    HashTable* h = new HashTable[size];
 
    char ksign[12];
    string kword[4];
 
    int nline;
    int n;
 
    string buffer;
    char buf[100];
 
public:
    Analyzer();
    ~Analyzer();
    void InputData(ifstream& fin);
    void OutputData(ofstream &fout);
    void Analyze();
    void Lexic(string lex);
    //void Syntax(ofstream &fsout);
    int Hash(string lex);
    void Print(ofstream& fout);
};
Почему выходит за границы массива в Analyze()?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.02.2016, 19:07
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Почему происходит выход за границы массива в функции Analyze()? (C++):

При вызове функции необработанное исключение, выход за границы массива
bool checkprocessed(point data,int xx,int yy,int wind) { bool mark=false;...

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

Выход за границы массива
Выхожу за пределы массива, но вот только не понимаю как. #include &lt;iostream&gt;...

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

Массивы: Проверка на выход за границы массива
Здравствуйте! Пишу код хождения коня по шахматной доске. Конь пока стоит на...

15
Ash_Evil_Dead
0 / 0 / 0
Регистрация: 26.12.2015
Сообщений: 11
15.02.2016, 19:15  [ТС] #2
Изменение размера массива не помогает.
Изначальный файл из которого считываем:
Кликните здесь для просмотра всего текста

int main ( ) {
for ( 10 ; 10 < 10 ; 10 + 1 )
a = a + b - a ;
goto c ;
c : a = k + a ;
return 1 ; }
0
nd2
2828 / 2398 / 1052
Регистрация: 29.01.2016
Сообщений: 8,022
15.02.2016, 19:58 #3
Цитата Сообщение от Ash_Evil_Dead Посмотреть сообщение
Почему выходит за границы массива в Analyze()?
В каком месте кода выходит?
0
Ash_Evil_Dead
0 / 0 / 0
Регистрация: 26.12.2015
Сообщений: 11
15.02.2016, 21:24  [ТС] #4
Добавлено через 18 минут
Цитата Сообщение от nd2 Посмотреть сообщение
В каком месте кода выходит?
Где-то здесь:
Цитата Сообщение от Ash_Evil_Dead Посмотреть сообщение
for (int i = 0; i < buffer.length(); i++)
* * {
* * * * string lex;
* * * * while ((buffer[i] != '\n') && (buffer[i] != ' '))
* * * * {
* * * * * * lex += buffer[i];
* * * * * * i++;
* * * * }
0
nd2
2828 / 2398 / 1052
Регистрация: 29.01.2016
Сообщений: 8,022
15.02.2016, 21:30 #5
Скорее всего, при последнем чтении, в конец строки не добавляется '\n'.
0
Ash_Evil_Dead
0 / 0 / 0
Регистрация: 26.12.2015
Сообщений: 11
15.02.2016, 21:43  [ТС] #6
Цитата Сообщение от nd2 Посмотреть сообщение
Скорее всего, при последнем чтении, в конец строки не добавляется '\n'.
buffer = "int main ( ) {\n
for ( 10 ; 10 < 10 ; 10 + 1 )\n
a = a + b - a ;\n
goto c ;\n
int i = 0 ;\n
c : a = k + a ;\n\
return 1 ; }\n"

Да не, там всё норм. Целый день мучаюсь, вообще ничего не понимаю.
0
nd2
2828 / 2398 / 1052
Регистрация: 29.01.2016
Сообщений: 8,022
15.02.2016, 21:52 #7
Цитата Сообщение от Ash_Evil_Dead Посмотреть сообщение
Да не, там всё норм.
Да, я тоже проверил, всё там добавляется.

Добавлено через 2 минуты
У меня, если смоделировать этот участок кода, с этим файлом, если убрать это: Lexic(lex);, то ошибок нет. Пройдись в отладчике, посмотри, что у тебя в buffer, где i выходит за границу, и пр.

Добавлено через 3 минуты
Найди точное место ошибки.
0
schdub
Эксперт С++
3016 / 1361 / 415
Регистрация: 19.01.2009
Сообщений: 3,613
Завершенные тесты: 1
15.02.2016, 21:53 #8
Цитата Сообщение от Ash_Evil_Dead Посмотреть сообщение
Да не, там всё норм. Целый день мучаюсь, вообще ничего не понимаю.
Ash_Evil_Dead, все равно. Если увеличивате i во внутреннем цикле, то нужно добавить i < buffer.length() в условия выхода.
1
Dreamer_0x01
258 / 85 / 30
Регистрация: 29.10.2015
Сообщений: 192
15.02.2016, 22:01 #9
Сделайте вывод значений переменных куда-нибудь - хоть в TRACE, хоть в консоль.
Вот в этих местах:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void Analyzer::Analyze()
{
 
    nline = 1;
    for (int i = 0; i < buffer.length(); i++)
    {
        string lex;
//вывести значение i , buffer.length(), и пометку "следующая итерация".
        while ((buffer[i] != '\n') && (buffer[i] != ' '))
        {
//вывести значение i и buffer.length(), и пометку "внутренний цикл"
            lex += buffer[i];
//вывести значение buffer[i]. На проблемном месте на предыдущей строке программа свалится, поэтому у вас останется в выводе значение i, на котором свалилось, и последний проанализированный символ.
            i++;
        }
        Lexic(lex);
        if (buffer[i] == '\n')
            nline++;
        lex = "";
    }
}
Есть у меня предположение, что у вас в строке после символа "\n" еще что-то есть. Например - "\n\r" .
Тогда на последней итерации цикла вы не дождетесь символа "\n". Вообще, у вас это опасный цикл, так как целостность программы зависит от введенных данных. Лучше не полениться и еще раз проверить i < buffer.length():
C++
1
while ((buffer[i] != '\n') && (buffer[i] != ' ') && (i < buffer.length()))
1
Ash_Evil_Dead
0 / 0 / 0
Регистрация: 26.12.2015
Сообщений: 11
15.02.2016, 22:27  [ТС] #10
Цитата Сообщение от nd2 Посмотреть сообщение
Найди точное место ошибки.
Странно, если Lexic(lex) в комментарии убирать, то все идеально работает.
Не понимаю, как Lexic может влиять на i.

Добавлено через 8 минут
Цитата Сообщение от Dreamer_0x01 Посмотреть сообщение
Есть у меня предположение, что у вас в строке после символа "\n" еще что-то есть. Например - "\n\r" .
Тогда на последней итерации цикла вы не дождетесь символа "\n". Вообще, у вас это опасный цикл, так как целостность программы зависит от введенных данных. Лучше не полениться и еще раз проверить i < buffer.length():
В консоли получается что-то такое, если Lexic(lex) в комментарии не убирать:
0)111) Следующая итерация! 0)111) Внутренний цикл! i
1)111) Внутренний цикл! n
2)111) Внутренний цикл! t
4)111) Следующая итерация! 4)111) Внутренний цикл! m
5)111) Внутренний цикл! a
6)111) Внутренний цикл! i
7)111) Внутренний цикл! n
9)111) Следующая итерация! 9)111) Внутренний цикл! (
11)111) Следующая итерация! 11)111) Внутренний цикл! )
13)111) Следующая итерация! 13)111) Внутренний цикл! {
15)111) Следующая итерация! 15)111) Внутренний цикл! f
16)111) Внутренний цикл! o
17)111) Внутренний цикл! r
19)111) Следующая итерация! 19)111) Внутренний цикл! (
21)111) Следующая итерация! 21)111) Внутренний цикл! 1
22)111) Внутренний цикл! 0
24)111) Следующая итерация! 24)111) Внутренний цикл! ;
26)111) Следующая итерация! 26)111) Внутренний цикл! 1
27)111) Внутренний цикл! 0
29)111) Следующая итерация! 29)111) Внутренний цикл! <
31)111) Следующая итерация! 31)111) Внутренний цикл! 1
32)111) Внутренний цикл! 0
34)111) Следующая итерация! 34)111) Внутренний цикл! ;
36)111) Следующая итерация! 36)111) Внутренний цикл! 1
37)111) Внутренний цикл! 0
39)111) Следующая итерация! 39)111) Внутренний цикл! +
41)111) Следующая итерация! 41)111) Внутренний цикл! 1
43)111) Следующая итерация! 43)111) Внутренний цикл! )
45)111) Следующая итерация! 45)111) Внутренний цикл! a
47)111) Следующая итерация! 47)111) Внутренний цикл! =
49)111) Следующая итерация! 49)111) Внутренний цикл! a
51)111) Следующая итерация! 51)111) Внутренний цикл! +
53)111) Следующая итерация! 53)111) Внутренний цикл! b
55)111) Следующая итерация! 55)111) Внутренний цикл! -
57)111) Следующая итерация! 57)111) Внутренний цикл! a
59)111) Следующая итерация! 59)111) Внутренний цикл! ;
61)111) Следующая итерация! 61)111) Внутренний цикл! g
62)111) Внутренний цикл! o
63)111) Внутренний цикл! t
64)111) Внутренний цикл! o
66)111) Следующая итерация! 66)111) Внутренний цикл! c
68)111) Следующая итерация! 68)111) Внутренний цикл! ;
70)111) Следующая итерация! 70)111) Внутренний цикл! i
71)111) Внутренний цикл! n
72)111) Внутренний цикл! t
74)111) Следующая итерация! 74)111) Внутренний цикл! i
76)111) Следующая итерация! 76)111) Внутренний цикл! =
78)111) Следующая итерация! 78)111) Внутренний цикл! 0
80)111) Следующая итерация! 80)111) Внутренний цикл! ;
82)111) Следующая итерация! 82)111) Внутренний цикл! c
84)111) Следующая итерация! 84)111) Внутренний цикл! :
86)111) Следующая итерация! 86)111) Внутренний цикл! a
88)111) Следующая итерация! 88)111) Внутренний цикл! =
90)111) Следующая итерация! 90)111) Внутренний цикл! k
92)111) Следующая итерация! 92)111) Внутренний цикл! +
94)111) Следующая итерация! 94)111) Внутренний цикл! a
0
Dreamer_0x01
258 / 85 / 30
Регистрация: 29.10.2015
Сообщений: 192
15.02.2016, 22:37 #11
Цитата Сообщение от Ash_Evil_Dead Посмотреть сообщение
c : a = k + a ;\n\
А вот этот слеш в конце - он действительно есть в данных, или это опечатка?

Добавлено через 2 минуты
Вот перед этим - вывод еще добавьте:
C++
1
2
//вывести: "lex=" и значение lex.
Lexic(lex);
0
Ash_Evil_Dead
0 / 0 / 0
Регистрация: 26.12.2015
Сообщений: 11
15.02.2016, 22:49  [ТС] #12
Цитата Сообщение от Dreamer_0x01 Посмотреть сообщение
А вот этот слеш в конце - он действительно есть в данных, или это опечатка?
Опечатка. Буфер в InputData нормально заполняется.

Добавлено через 11 минут
Цитата Сообщение от Dreamer_0x01 Посмотреть сообщение
Вот перед этим - вывод еще добавьте:
0)111) Следующая итерация! 0)111 Внутренний цикл! i
1)111 Внутренний цикл! n
2)111 Внутренний цикл! t
lex=int
4)111) Следующая итерация! 4)111 Внутренний цикл! m
5)111 Внутренний цикл! a
6)111 Внутренний цикл! i
7)111 Внутренний цикл! n
lex=main
9)111) Следующая итерация! 9)111 Внутренний цикл! (
lex=(
11)111) Следующая итерация! 11)111 Внутренний цикл! )
lex=)
13)111) Следующая итерация! 13)111 Внутренний цикл! {
lex={
15)111) Следующая итерация! 15)111 Внутренний цикл! f
16)111 Внутренний цикл! o
17)111 Внутренний цикл! r
lex=for
19)111) Следующая итерация! 19)111 Внутренний цикл! (
lex=(
21)111) Следующая итерация! 21)111 Внутренний цикл! 1
22)111 Внутренний цикл! 0
lex=10
24)111) Следующая итерация! 24)111 Внутренний цикл! ;
lex=;
26)111) Следующая итерация! 26)111 Внутренний цикл! 1
27)111 Внутренний цикл! 0
lex=10
29)111) Следующая итерация! 29)111 Внутренний цикл! <
lex=<
31)111) Следующая итерация! 31)111 Внутренний цикл! 1
32)111 Внутренний цикл! 0
lex=10
34)111) Следующая итерация! 34)111 Внутренний цикл! ;
lex=;
36)111) Следующая итерация! 36)111 Внутренний цикл! 1
37)111 Внутренний цикл! 0
lex=10
39)111) Следующая итерация! 39)111 Внутренний цикл! +
lex=+
41)111) Следующая итерация! 41)111 Внутренний цикл! 1
lex=1
43)111) Следующая итерация! 43)111 Внутренний цикл! )
lex=)
45)111) Следующая итерация! 45)111 Внутренний цикл! a
lex=a
47)111) Следующая итерация! 47)111 Внутренний цикл! =
lex==
49)111) Следующая итерация! 49)111 Внутренний цикл! a
lex=a
51)111) Следующая итерация! 51)111 Внутренний цикл! +
lex=+
53)111) Следующая итерация! 53)111 Внутренний цикл! b
lex=b
55)111) Следующая итерация! 55)111 Внутренний цикл! -
lex=-
57)111) Следующая итерация! 57)111 Внутренний цикл! a
lex=a
59)111) Следующая итерация! 59)111 Внутренний цикл! ;
lex=;
61)111) Следующая итерация! 61)111 Внутренний цикл! g
62)111 Внутренний цикл! o
63)111 Внутренний цикл! t
64)111 Внутренний цикл! o
lex=goto
66)111) Следующая итерация! 66)111 Внутренний цикл! c
lex=c
68)111) Следующая итерация! 68)111 Внутренний цикл! ;
lex=;
70)111) Следующая итерация! 70)111 Внутренний цикл! i
71)111 Внутренний цикл! n
72)111 Внутренний цикл! t
lex=int
74)111) Следующая итерация! 74)111 Внутренний цикл! i
lex=i
76)111) Следующая итерация! 76)111 Внутренний цикл! =
lex==
78)111) Следующая итерация! 78)111 Внутренний цикл! 0
lex=0
80)111) Следующая итерация! 80)111 Внутренний цикл! ;
lex=;
82)111) Следующая итерация! 82)111 Внутренний цикл! c
lex=c
84)111) Следующая итерация! 84)111 Внутренний цикл! :
lex=:
86)111) Следующая итерация! 86)111 Внутренний цикл! a
lex=a
88)111) Следующая итерация! 88)111 Внутренний цикл! =
lex==
90)111) Следующая итерация! 90)111 Внутренний цикл! k
lex=k
92)111) Следующая итерация! 92)111 Внутренний цикл! +
lex=+
94)111) Следующая итерация! 94)111 Внутренний цикл! a
lex=a
0
Dreamer_0x01
258 / 85 / 30
Регистрация: 29.10.2015
Сообщений: 192
15.02.2016, 23:03 #13
Цитата Сообщение от Dreamer_0x01 Посмотреть сообщение
while ((buffer[i] != '\n') && (buffer[i] != ' ') && (i < buffer.length()))
Вот такая проверка сейчас есть в коде?

Вообще, как сейчас код выглядит, и на какой строке (№) вылетает?
0
Ash_Evil_Dead
0 / 0 / 0
Регистрация: 26.12.2015
Сообщений: 11
15.02.2016, 23:08  [ТС] #14
Цитата Сообщение от Dreamer_0x01 Посмотреть сообщение
Вот такая проверка сейчас есть в коде?
Да, есть.

Добавлено через 1 минуту
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void Analyzer::Analyze()
{
    setlocale(LC_ALL, "Russian");
    nline = 1;
    for (int i = 0; i < buffer.length(); i++)
    {
        string lex;
        cout << i<<")";
        cout << buffer.length() <<") Следующая итерация! ";
        while ((buffer[i] != '\n') && (buffer[i] != ' ') && (i < buffer.length()))
        {
            cout << i << ")";
            cout << buffer.length() << " Внутренний цикл! ";
            lex += buffer[i];
            cout << buffer[i]<<endl;
            i++;
        }
        cout << " lex=" << lex<<endl;
        Lexic(lex);
        if (buffer[i] == '\n')
            nline++;
    }
}
Analyze чуть-чуть поменял.

Добавлено через 46 секунд
Цитата Сообщение от Dreamer_0x01 Посмотреть сообщение
на какой строке (№) вылетает?
Он не вылетает, ошибку не выдает, просто зависает. Может потеря памяти где-то?
0
nd2
2828 / 2398 / 1052
Регистрация: 29.01.2016
Сообщений: 8,022
15.02.2016, 23:10 #15
Ash_Evil_Dead, ты нашёл точное место вылета? Отладчиком не умеешь пользоваться?

Добавлено через 46 секунд
Цитата Сообщение от Ash_Evil_Dead Посмотреть сообщение
Он не вылетает, ошибку не выдает, просто зависает.
Зачем тогда это пишешь?
Цитата Сообщение от Ash_Evil_Dead Посмотреть сообщение
Почему выходит за границы массива в Analyze()?
1
Ash_Evil_Dead
0 / 0 / 0
Регистрация: 26.12.2015
Сообщений: 11
15.02.2016, 23:22  [ТС] #16
Цитата Сообщение от nd2 Посмотреть сообщение
Зачем тогда это пишешь?
Думал изначально, что выходит за границы.

Добавлено через 42 секунды
Нашел проблему, неправильно Хэш искал, всем большое спасибо.
0
15.02.2016, 23:22
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.02.2016, 23:22
Привет! Вот еще темы с решениями:

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

Как вызвать исключение «выход за границы массива»?
Как вызвать исключение «выход за границы массива»? То есть, чтобы ввели массив...

Происходит выход из функции при попытке считывания текста в переменную
Почему при попытке записать текст на английском языке в str.maker выходит из...

Ошибка деструктора - В конструкторе происходит выход за границу массива
Доброго времени. #include &lt;iostream.h&gt; #include &lt;math.h&gt; class OKTAVE {...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru