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

Не изменяется элемент вектора при работе с ним по указателю - C++

Восстановить пароль Регистрация
 
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
07.06.2013, 21:31     Не изменяется элемент вектора при работе с ним по указателю #1
Здравствуйте. Проблема следующая. Пишу свою велосипедную (на это, как на источник проблемы, не указывать) реализацию бинарного дерева для своего не менее велосипедного архиватора, использующего алгоритм Хаффмана. Составление нового кода для каждого символа происходит в отдельной функции, которая в качестве аргумента принимает указатель на структуру соответствующего символа. Структуры хранятся в специальном векторе. Однако, происходит так, что изменение структуры в функции никак не влияет на нее же в векторе (см. скриншот). Нахожусь в полной расстерянности, помогите, пожалуйста, разобраться.
Миниатюры
Не изменяется элемент вектора при работе с ним по указателю  
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.06.2013, 21:31     Не изменяется элемент вектора при работе с ним по указателю
Посмотрите здесь:

Наибольший элемент вектора C++
C++ Извлечь элемент из вектора
Как в односвязном списке поменять местами один элемент и следующий за ним? C++
Определить количество положительных элементов вектора С(10) и заменить этим значением минимальный элемент вектора А(5) C++
Слетает прога при присваивании разименованованному указателю C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
07.06.2013, 22:16     Не изменяется элемент вектора при работе с ним по указателю #2
Цитата Сообщение от qpMM Посмотреть сообщение
Составление нового кода для каждого символа происходит в отдельной функции, которая в качестве аргумента принимает указатель на структуру соответствующего символа.
Вызов функции покажите.
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
07.06.2013, 22:18  [ТС]     Не изменяется элемент вектора при работе с ним по указателю #3
Цитата Сообщение от alsav22 Посмотреть сообщение
Вызов функции покажите.
C++
1
setNewByte(&bytes[0]);
bytes[0] содержит структуру конечного псевдосимвола, то есть является началом дерева.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
07.06.2013, 22:38     Не изменяется элемент вектора при работе с ним по указателю #4
Почему изменения по индексу 3 смотрите?
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
07.06.2013, 22:47  [ТС]     Не изменяется элемент вектора при работе с ним по указателю #5
Цитата Сообщение от alsav22 Посмотреть сообщение
Почему изменения по индексу 3 смотрите?
Потому что node в момент выполнения функции указывает на этот элемент. Идентичность содержимого этого указателя и элемента с индексом 3 очевидна.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
07.06.2013, 23:01     Не изменяется элемент вектора при работе с ним по указателю #6
Цитата Сообщение от qpMM Посмотреть сообщение
Идентичность содержимого этого указателя и элемента с индексом 3 очевидна.
Очевидна для того, кто скрин видит? Или для того, кто код видит?
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
07.06.2013, 23:25  [ТС]     Не изменяется элемент вектора при работе с ним по указателю #7
Цитата Сообщение от alsav22 Посмотреть сообщение
кто скрин видит?
Да. В коде изменения переменной во время выполнения программы вы не увидите. На скриншоте идентичность показана розовой и оранжевой черточками. То, что указатель в запечатленный момент указывает на этот элемент показано красной и фиолетовой черточками. Плюс ко всему, проблемный участок кода также виден на скриншоте. Из остального кода к этой функции (помимо вызова) относится только то, что вектор nodes объявлен глобально, чтобы я мог просматривать его содержимое.

Добавлено через 9 минут
Ну, точнее розовая показывает как раз отличие. Вместо newByte сравните переменные freq.

Добавлено через 5 минут
Вектор nodes - изменяемый вектор.

Хотя, в любом случае я должен был сделать это раньше:
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
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
#include <algorithm>
 
using namespace std;
 
struct byte
{
    char oldByte=0;
    char newByte=0;
    byte *left=NULL;
    byte *right=NULL;
    int freq=1;
} tempByte;
 
vector<byte> nodes;
 
bool find_match(vector<byte> &bytes, char symbol)
{
    for (auto &el: bytes)
    {
        if (el.oldByte == symbol)
        {
            el.freq++;
            return true;
        }
    }
    return false;
}
 
bool compareElem(byte first, byte second)
{
    return (first.freq > second.freq); // from higher to lower
}
 
void setNewByte(byte *node)
{
    static bitset<8> tempNewByte; // 00000000
 
    if (node->left && !node->left->newByte) // or newByte!=-1 (or isSet!=true)
    {
        tempNewByte<<=1;
        tempNewByte[0]=1;
 
        setNewByte(node->left);
    }
    else
    {
        node->newByte=(char)tempNewByte.to_ulong();
        tempNewByte>>=1;
    }
 
    if (node->right && !node->right->newByte)
    {
        tempNewByte<<=1;
        tempNewByte[0]=0;
 
        setNewByte(node->right);
    }
}
 
void printBinary(char num)
{
    int bits[8]={0}, i;
 
    for(i=7; i>=0; i--)
    {
        bits[i]=(num & 1 ? 1 : 0);
        num>>=1;
    }
 
    for(i=0; i<8; i++) cout << bits[i];
}
 
int main(int argc, char *argv[])
{
    ifstream input("/home/qpmmy/Coding/test", ios::binary);
 
    vector<byte> bytes;
    vector<byte>::iterator p;
    nodes.push_back(tempByte);
 
    if (!input)
    {
        cout << "Error while opening files. Press Enter to exit.";
        getchar();
        return 1;
    }
 
    while( (tempByte.oldByte=input.get()) != EOF )
    {
        if (!find_match(bytes, tempByte.oldByte)) bytes.push_back(tempByte);
    }
 
    for(p=bytes.end()-1; bytes.size()!=1; p=bytes.end()-1)
    {
        stable_sort(bytes.begin(), bytes.end(), compareElem);
 
        tempByte.oldByte=bytes.size()-5;
        tempByte.freq=p->freq+(p-1)->freq;
 
        nodes.insert(nodes.end(), bytes.end()-2, bytes.end());
        bytes.erase(bytes.end()-2, bytes.end());
 
        tempByte.left=&nodes[nodes.size()-2];
        tempByte.right=&nodes[nodes.size()-1];
 
        bytes.push_back(tempByte);
    }
 
    setNewByte(&bytes[0]);
 
    for(auto n: nodes)
    {
        if (!n.left)
        {
            cout << "oldByte is (" << n.oldByte << ") "; printBinary(n.oldByte); cout << endl;
            cout << "newByte is (" << n.newByte << ") "; printBinary(n.newByte); cout << endl;
            cout << "left is " << n.left << endl;
            cout << "right is " << n.right << endl;
            cout << "freq is " << n.freq << "\n\n";
        }
    }
 
    input.close();
 
    return 0;
}
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
07.06.2013, 23:29     Не изменяется элемент вектора при работе с ним по указателю #8
Цитата Сообщение от qpMM Посмотреть сообщение
В коде изменения переменной во время выполнения программы вы не увидите.
Я не про изменение, а про очевидность идентичности писал.
Цитата Сообщение от qpMM Посмотреть сообщение
То, что указатель в запечатленный момент указывает на этот элемент показано красной и фиолетовой черточками.
Чёрточки же вы рисовали. Кроме чёрточек, ещё что-либо указывает на то, что указатель в данный момент связан именно с этим элементом? Что с теми элементами, которые до него в функцию передавались (с индексом 0, 1, 2)? Как с ними дело обстояло? Так же? Ошибок в куске кода я не вижу. Если сможете выложить весь код, то попытаюсь найти причину.
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
07.06.2013, 23:38  [ТС]     Не изменяется элемент вектора при работе с ним по указателю #9
Цитата Сообщение от alsav22 Посмотреть сообщение
Если сможете выложить весь код, то попытаюсь найти причину.
Отредактировал.

Добавлено через 4 минуты
Цитата Сообщение от alsav22 Посмотреть сообщение
Кроме чёрточек, ещё что-либо указывает на то, что указатель в данный момент связан именно с этим элементом?
Эти черточками я хотел показать, что указатель node имеет такой-то адрес, в содержимом по которому есть символ i, имеющий отношение только к одному элементу в векторе. Нулевой элемент вектора (который не видно в скрине) nodes пустой (строка 83 в коде) и вообще не используется по той причине, что адрес нулевого элемента отчего-то меняется в процессе выполнения программы.

Добавлено через 2 минуты
Цитата Сообщение от alsav22 Посмотреть сообщение
Что с теми элементами, которые до него в функцию передавались (с индексом 0, 1, 2)?
С ними та же ситуация.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
07.06.2013, 23:44     Не изменяется элемент вектора при работе с ним по указателю #10
Цитата Сообщение от qpMM Посмотреть сообщение
по той причине, что адрес нулевого элемента отчего-то меняется в процессе выполнения программы.
Я так понимаю, кроме заявленной темы есть и ещё непонятное?

Добавлено через 3 минуты

Не по теме:

Цитата Сообщение от qpMM Посмотреть сообщение
Хотя, в любом случае я должен был сделать это раньше:
С++ 11 приветствую тебя!!!

qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
07.06.2013, 23:52  [ТС]     Не изменяется элемент вектора при работе с ним по указателю #11
Цитата Сообщение от alsav22 Посмотреть сообщение
Я так понимаю, кроме заявленной темы есть и ещё непонятное?
Есть такое Но это непонятное устранено (не нулевые элементы вектора свои адреса во время выполнения программы не меняют), так что решил не упоминать.

Добавлено через 4 минуты

Не по теме:

Цитата Сообщение от alsav22 Посмотреть сообщение
С++ 11 приветствую тебя!!
Помимо auto, кстати, попытался использовать функцию move (вместо использования insert и erase), но отчего-то () программа в этом случае заканчивалась SEGFAULT'ом.

alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2013, 00:01     Не изменяется элемент вектора при работе с ним по указателю #12

Не по теме:

Цитата Сообщение от qpMM Посмотреть сообщение
Помимо auto, кстати, попытался использовать функцию move (вместо использования insert и erase)
Я по поводу С++ 11 написал потому, что у меня среда не понимает С++ 11.


Файл можете выложить, который используете в коде?

Добавлено через 1 минуту
Цитата Сообщение от qpMM Посмотреть сообщение
Но это непонятное устранено (не нулевые элементы вектора свои адреса во время выполнения программы не меняют), так что решил не упоминать.
Это только больше всё запутывает.
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
08.06.2013, 00:04  [ТС]     Не изменяется элемент вектора при работе с ним по указателю #13
Цитата Сообщение от alsav22 Посмотреть сообщение
Файл можете выложить, который используете в коде?
Расширение пришлось добавить - для загрузки.
Вложения
Тип файла: txt test.txt (7 байт, 3 просмотров)
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2013, 02:48     Не изменяется элемент вектора при работе с ним по указателю #14
Если так:
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
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
#include <algorithm>
#include <cstdlib>
 
using namespace std;
 
struct byte
{
    char oldByte=0;
    char newByte=0;
    byte *left=NULL;
    byte *right=NULL;
    int freq=1;
} tempByte;
 
vector<byte> nodes;
 
bool find_match(vector<byte> &bytes, char symbol)
{
    for (auto &el: bytes)
    {
        if (el.oldByte == symbol)
        {
            el.freq++;
            return true;
        }
    }
    return false;
}
 
bool compareElem(byte first, byte second)
{
    return (first.freq > second.freq); // from higher to lower
}
 
void setNewByte(byte *node)
{
    static bitset<8> tempNewByte; // 00000000
 
    if (node->left && !node->left->newByte) // or newByte!=-1 (or isSet!=true)
    {
        tempNewByte<<=1;
        tempNewByte[0]=1;
 
        setNewByte(node->left);
    }
    else
    {
        node->newByte=(char)tempNewByte.to_ulong();
        tempNewByte>>=1;
    }
 
    if (node->right && !node->right->newByte)
    {
        tempNewByte<<=1;
        tempNewByte[0]=0;
 
        setNewByte(node->right);
    }
}
 
void printBinary(char num)
{
    int bits[8]={0}, i;
 
    for(i=7; i>=0; i--)
    {
        bits[i]=(num & 1 ? 1 : 0);
        num>>=1;
    }
 
    for(i=0; i<8; i++) cout << bits[i];
}
 
int main(int argc, char *argv[])
{
    ifstream input("/home/qpmmy/Coding/test", ios::binary);
 
    vector<byte> bytes;
    bytes.reserve(10);
    nodes.reserve(10);
    vector<byte>::iterator p;
    //nodes.push_back(tempByte);
 
    if (!input)
    {
        cout << "Error while opening files. Press Enter to exit.";
        getchar();
        return 1;
    }
 
    while( (tempByte.oldByte=input.get()) != EOF )
    {
        if (!find_match(bytes, tempByte.oldByte)) bytes.push_back(tempByte);
    }
 
    for(p=bytes.end()-1; bytes.size()!=1; p=bytes.end()-1)
    {
        stable_sort(bytes.begin(), bytes.end(), compareElem);
 
        tempByte.oldByte=bytes.size()-5;
        tempByte.freq=p->freq+(p-1)->freq;
 
        nodes.insert(nodes.end(), bytes.end()-2, bytes.end());
        bytes.erase(bytes.end()-2, bytes.end());
 
        tempByte.left=&nodes[nodes.size()-2];
        tempByte.right=&nodes[nodes.size()-1];
 
        bytes.push_back(tempByte);
    }
 
    setNewByte(&bytes[0]);
 
    for(auto n: nodes)
    {
        if (!n.left)
        {
            cout << "oldByte is (" << n.oldByte << ") "; printBinary(n.oldByte); cout << endl;
            cout << "newByte is (" << n.newByte << ") "; printBinary(n.newByte); cout << endl;
            cout << "left is " << n.left << endl;
            cout << "right is " << n.right << endl;
            cout << "freq is " << n.freq << "\n\n";
        }
    }
 
    input.close();
 
    system("pause");
    return 0;
}
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
08.06.2013, 15:46  [ТС]     Не изменяется элемент вектора при работе с ним по указателю #15
Цитата Сообщение от alsav22 Посмотреть сообщение
C++
1
2
bytes.reserve(10); 
nodes.reserve(10);
Сработало. Большое спасибо, вопрос исчерпан.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2013, 15:59     Не изменяется элемент вектора при работе с ним по указателю #16
Только учитывайте, что это достаточный резерв для данного файла, для большего нужно больше резервировать, а лучше сразу с запасом.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.06.2013, 16:04     Не изменяется элемент вектора при работе с ним по указателю
Еще ссылки по теме:

C++ Найти максимальный элемент (из 10 чисел) и следующий за ним максимальный элемент
C++ Push_back вектора по указателю - возможно ли

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

Или воспользуйтесь поиском по форуму:
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
08.06.2013, 16:04  [ТС]     Не изменяется элемент вектора при работе с ним по указателю #17
Цитата Сообщение от alsav22 Посмотреть сообщение
лучше сразу с запасом
Да, я вот так сделал:
C++
1
2
3
4
5
6
input.seekg(0, input.end);
reserveSize=input.tellg();
input.seekg(0, input.beg);
 
bytes.reserve(reserveSize*2);
nodes.reserve(reserveSize*2); // при случае nodes по крайней мере сможет вместить в себя весь bytes + все псевдосимволы
Вдруг кому-то пригодится.
Yandex
Объявления
08.06.2013, 16:04     Не изменяется элемент вектора при работе с ним по указателю
Ответ Создать тему
Опции темы

Текущее время: 06:49. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru