Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Norfolks
0 / 0 / 0
Регистрация: 07.11.2013
Сообщений: 4
#1

Обнаружением нулевого указателя - C++

07.11.2013, 21:55. Просмотров 366. Ответов 9
Метки нет (Все метки)

Делаю алгоритм Хаффмана. Возникла проблема при построении таблицы соответствий.

C++
1
2
3
4
5
6
7
8
9
10
11
12
void MakeT (Node* root){
    if(root->L!=NULL) {//проблемная строка
        code.push_back(0);
        MakeT(root->L);
    }
    if(root->R!=NULL) {
        code.push_back(1);
        MakeT(root->R);
    }
    table[root->c]=code;
    code.pop_back();
}
Возникает ошибка:"Необработанное исключение в "0x01102541" в "Haffman.exe": 0xC0000005: Нарушение прав доступа при чтении "0xcdcdcdd5"."
Т.е. грубо говоря if не работает и пропускает нулевой указатель.

Причем код такого типа в главной функции работает верно.
C++
1
2
while(root->L!=NULL)
        root=root->L;
Помогите пожалуйста)
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.11.2013, 21:55
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Обнаружением нулевого указателя (C++):

Разыменование нулевого указателя - C++
Как вообще по стандарту ведет себя программа после разыменования нулевого указателя? Указано-ли это явно? Просто сегодня на работе...

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

Вызов delete для нулевого указателя - C++
Здравствуйте. Прочитал про конструктор переноса, в котором при копировании, необходимо обнулить все указатели, чтобы при удалении...

Null или 0 для нулевого указателя - C++
Здравствуйте. Появился вопрос что использовать лучше для создания нулевого указателя null или 0?

почему не происходит разыменования нулевого указателя? - C++
вот думаю, почему сия конструкция не вылетает: #define offsetof(type, member) (size_t)(&(((type*)nullptr)->member))... видимо не происходит...

Бинарные деревья. Ошибка нулевого указателя - C++
При выполнении программы возникла следующая ошибка: ptr было nullptr. Что это значит и как ее исправить?Возникает в функции make в цикле...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Croessmah
Эксперт CЭксперт С++
13231 / 7503 / 846
Регистрация: 27.09.2012
Сообщений: 18,428
Записей в блоге: 3
Завершенные тесты: 1
07.11.2013, 21:58 #2
Цитата Сообщение от Norfolks Посмотреть сообщение
Помогите пожалуйста
И что мы должны понять из приведенного куска?
понятно только, что если root == NUL, то беда.
А вообще причем проверка на NULL и вышеуказанная ошибка не понятно.
2
castaway
Эксперт С++
4884 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
07.11.2013, 21:58 #3
Цитата Сообщение от Norfolks Посмотреть сообщение
Т.е. грубо говоря if не работает и пропускает нулевой указатель.
Почему ты решил что он его "пропускает"?
0
Alex0491
0 / 0 / 0
Регистрация: 07.11.2013
Сообщений: 15
07.11.2013, 22:10 #4
Скорее всего не определён параметр root.
Такое исключение выскакивает когда пытаешь произвести чтение/запись по неверному адресу.

Проверь, создан ли объект по этому указателю. Ошибку скорее всего вызывает выражение root->L

P.S. Из приведенного куска кода и правда мало что понятно. Выложи код, где ты передаешь значение в MakeT (Node* root), и структуру Node
0
Norfolks
0 / 0 / 0
Регистрация: 07.11.2013
Сообщений: 4
07.11.2013, 22:22  [ТС] #5
Цитата Сообщение от Croessmah Посмотреть сообщение
И что мы должны понять из приведенного куска?
Цитата Сообщение от castaway Посмотреть сообщение
Почему ты решил что он его "пропускает"?
Цитата Сообщение от Alex0491 Посмотреть сообщение
Из приведенного куска кода и правда мало что понятно. Выложи код, где ты передаешь значение в MakeT (Node* root), и структуру Node
Попытаюсь описать подробнее

Функция MakeT() должна рекурсивно проходить по древу и натыкаясь в определённый момент в конец ветки т.е. когда следующий root->L не инициализирован, проверить правый отросток ну и т.д.

Но по некой неведомой причине в тот момент когда root->L==NULL if пропускает это мимо ушей вследствие чего MakeT запускается с нулевым указателем ( MakeT(NULL)) и в самой функции происходит вызов NULL->L, что вызывает ошибку.



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
struct Node {
    unsigned int power;
    char c;
    Node* L, *R;
    
};
//создание элементов дерева
for(im=h.begin();im!=h.end();im++){
        Node* p = new Node;
        p->power = im->second;
        p->c = im->first;
        t.push_back(p);
    }
//создание дерева
while(t.size()>1){
    t.sort(MySort());
    Node* L=t.front();
    t.pop_front();
    Node* R=t.front();
    t.pop_front();
 
    Node* p=new Node;
    p->L=L;
    p->R=R;
    p->power=L->power+R->power;
    t.push_back(p); 
}
    
Node* root= t.front();
MakeT(root);
Добавлено через 5 минут
На всякий случай полный код
Кликните здесь для просмотра всего текста
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
#include<iostream>
#include<vector>
#include<map>
#include<list>
 
using namespace std;
 
struct Node {
    unsigned int power;
    char c;
    Node* L, *R;
    
};
 
struct MySort{
    bool operator()(Node *l,Node *r)
        {return (*l).power<(*r).power;}
};
 
 
vector <int> code;
map<char, vector<int>> table;
 
void MakeT (Node* root){
    if(root->L!=NULL) {
        code.push_back(0);
        MakeT(root->L);
    }
    if(root->R!=NULL) {
        code.push_back(1);
        MakeT(root->R);
    }
    table[root->c]=code;
    code.pop_back();
}
 
 
 
 
 
int main(){
    map<char,int> h;
    map<char,int>::iterator im;
 
    FILE* F=fopen("D:\\M.txt","rb");
    char buf;
 
    while(fread(&buf,1,1,F)){
        h[buf]++;   
    }
 
 
    fseek(F,0,SEEK_SET);
    std::list<Node*> t;
    for(im=h.begin();im!=h.end();im++){
        Node* p = new Node;
        p->power = im->second;
        p->c = im->first;
        t.push_back(p);
    }
 
    while(t.size()>1){
        t.sort(MySort());
        Node* L=t.front();
        t.pop_front();
        Node* R=t.front();
        t.pop_front();
 
        Node* p=new Node;
        p->L=L;
        p->R=R;
        p->power=L->power+R->power;
        t.push_back(p); 
    }
    
    Node* root= t.front();
    MakeT(root);
    fseek(F,SEEK_SET,0);
    FILE* HAFM=fopen("D:\\Haff.txt","rb");
    char cr, count=0;
    while(fread(&buf,1,1,F)){
        for(int i=0;i<table[buf].size();i++){
            cr=cr|(table[buf][i]<<count);
            count++;
            if(count==8){
                count=0;
                fwrite(&cr,1,1,HAFM);
            }
        }
    
    }
 
    return 0;
 
}
0
Croessmah
Эксперт CЭксперт С++
13231 / 7503 / 846
Регистрация: 27.09.2012
Сообщений: 18,428
Записей в блоге: 3
Завершенные тесты: 1
07.11.2013, 22:25 #6
Содержимое файла каково?
0
Norfolks
0 / 0 / 0
Регистрация: 07.11.2013
Сообщений: 4
07.11.2013, 22:27  [ТС] #7
Цитата Сообщение от Croessmah Посмотреть сообщение
Содержимое файла каково?
"Hello kitty!!!!!"
0
Croessmah
Эксперт CЭксперт С++
13231 / 7503 / 846
Регистрация: 27.09.2012
Сообщений: 18,428
Записей в блоге: 3
Завершенные тесты: 1
07.11.2013, 22:44 #8
C++
1
2
3
4
5
6
7
8
    for(im=h.begin();im!=h.end();im++){
        Node* p = new Node;
        p->power = im->second;
        p->c = im->first;
        p -> L = NULL ;//Обнулять кто будет???
        p -> R = NULL ;//Обнулять кто будет???
        t.push_back(p);
    }
Не инициализировали указатели

Добавлено через 44 секунды
C++
1
FILE* HAFM=fopen("D:\\Haff.txt","rb");
файл открываете для чтения, а потом пишите в него. Откройте для записи "wb"
2
Norfolks
0 / 0 / 0
Регистрация: 07.11.2013
Сообщений: 4
07.11.2013, 22:50  [ТС] #9
Цитата Сообщение от Croessmah Посмотреть сообщение
Не инициализировали указатели
Хм до этого пробовал исключительно p -> L = NULL или p -> R = NULL

Огромное спасибо!
0
Alex0491
0 / 0 / 0
Регистрация: 07.11.2013
Сообщений: 15
07.11.2013, 22:51 #10
Цитата Сообщение от Croessmah Посмотреть сообщение
Код C++
1
2
3
4
5
6
7
8
* * for(im=h.begin();im!=h.end();im++){
* * * * Node* p = new Node;
* * * * p->power = im->second;
* * * * p->c = im->first;
* * * * p -> L = NULL ;//Обнулять кто будет???
* * * * p -> R = NULL ;//Обнулять кто будет???
* * * * t.push_back(p);
* * }
Не инициализировали указатели
Это не очень изящное решение. Код и так абсолютно не нагляден, не стоит его засорять ещё сильнее. раз этот указатель - член класса, то класс и должен позаботиться о его инициализации:
C++
1
2
3
4
5
6
7
8
9
10
struct Node {
    unsigned int power;
    char c;
    Node* L, *R;
 
    Node()  //конструктор
    {
        L = R = 0;
    }
};
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.11.2013, 22:51
Привет! Вот еще темы с ответами:

Почему увеличение указателя на sizeof(тип) не тождественно инкременту этого же указателя? - C++
Всем доброго дня.:) Можете обьяснить ,почему при инкриментировании указателя,его значение(адресс) увеличивается на 4 (размер int в...

Как сделать функцию от указателя на класс и указателя на метод? - C++
Не получается сделать функцию, параметрами которой являются указатель на класс и на метод. Обращаться к классу нужно именно по указателю,...

Преобразование кода без указателя в код с использованием указателя - C++
Правильно ли выполнил? Исходный код без указателя #include &lt;iostream&gt; #include &lt;cstdlib&gt; #include &lt;fstream&gt; using namespace...

В чём отличие константного указателя и указателя на константу? - C++
int *const p1 и int const* p2 Объясните мне в чём тут отличие.


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
07.11.2013, 22:51
Ответ Создать тему
Опции темы

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