0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
1

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

07.06.2013, 21:31. Показов 1870. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте. Проблема следующая. Пишу свою велосипедную (на это, как на источник проблемы, не указывать) реализацию бинарного дерева для своего не менее велосипедного архиватора, использующего алгоритм Хаффмана. Составление нового кода для каждого символа происходит в отдельной функции, которая в качестве аргумента принимает указатель на структуру соответствующего символа. Структуры хранятся в специальном векторе. Однако, происходит так, что изменение структуры в функции никак не влияет на нее же в векторе (см. скриншот). Нахожусь в полной расстерянности, помогите, пожалуйста, разобраться.
Миниатюры
Не изменяется элемент вектора при работе с ним по указателю  
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.06.2013, 21:31
Ответы с готовыми решениями:

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

HDD отключается при работе с ним
Короче, трабла такая. Основной диск переодически отрубается когда пользуешься им (нет никакого...

Push_back вектора по указателю - возможно ли
Я хочу объявить вектор в одной функции и работать с ним методами в другой. Самый простой путь -...

Передача вектора в функцию по указателю
Есть функция с таким прототипом: void Split(const string& text, char delimeter, const...

16
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
07.06.2013, 22:16 2
Цитата Сообщение от qpMM Посмотреть сообщение
Составление нового кода для каждого символа происходит в отдельной функции, которая в качестве аргумента принимает указатель на структуру соответствующего символа.
Вызов функции покажите.
0
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
07.06.2013, 22:18  [ТС] 3
Цитата Сообщение от alsav22 Посмотреть сообщение
Вызов функции покажите.
C++
1
setNewByte(&bytes[0]);
bytes[0] содержит структуру конечного псевдосимвола, то есть является началом дерева.
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
07.06.2013, 22:38 4
Почему изменения по индексу 3 смотрите?
0
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
07.06.2013, 22:47  [ТС] 5
Цитата Сообщение от alsav22 Посмотреть сообщение
Почему изменения по индексу 3 смотрите?
Потому что node в момент выполнения функции указывает на этот элемент. Идентичность содержимого этого указателя и элемента с индексом 3 очевидна.
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
07.06.2013, 23:01 6
Цитата Сообщение от qpMM Посмотреть сообщение
Идентичность содержимого этого указателя и элемента с индексом 3 очевидна.
Очевидна для того, кто скрин видит? Или для того, кто код видит?
0
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;
}
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
07.06.2013, 23:29 8
Цитата Сообщение от qpMM Посмотреть сообщение
В коде изменения переменной во время выполнения программы вы не увидите.
Я не про изменение, а про очевидность идентичности писал.
Цитата Сообщение от qpMM Посмотреть сообщение
То, что указатель в запечатленный момент указывает на этот элемент показано красной и фиолетовой черточками.
Чёрточки же вы рисовали. Кроме чёрточек, ещё что-либо указывает на то, что указатель в данный момент связан именно с этим элементом? Что с теми элементами, которые до него в функцию передавались (с индексом 0, 1, 2)? Как с ними дело обстояло? Так же? Ошибок в куске кода я не вижу. Если сможете выложить весь код, то попытаюсь найти причину.
0
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)?
С ними та же ситуация.
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
07.06.2013, 23:44 10
Цитата Сообщение от qpMM Посмотреть сообщение
по той причине, что адрес нулевого элемента отчего-то меняется в процессе выполнения программы.
Я так понимаю, кроме заявленной темы есть и ещё непонятное?

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

Не по теме:

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

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

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

Не по теме:

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

0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2013, 00:01 12

Не по теме:

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


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

Добавлено через 1 минуту
Цитата Сообщение от qpMM Посмотреть сообщение
Но это непонятное устранено (не нулевые элементы вектора свои адреса во время выполнения программы не меняют), так что решил не упоминать.
Это только больше всё запутывает.
0
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
08.06.2013, 00:04  [ТС] 13
Цитата Сообщение от alsav22 Посмотреть сообщение
Файл можете выложить, который используете в коде?
Расширение пришлось добавить - для загрузки.
Вложения
Тип файла: txt test.txt (7 байт, 4 просмотров)
0
5498 / 4893 / 831
Регистрация: 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;
}
1
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
08.06.2013, 15:46  [ТС] 15
Цитата Сообщение от alsav22 Посмотреть сообщение
C++
1
2
bytes.reserve(10); 
nodes.reserve(10);
Сработало. Большое спасибо, вопрос исчерпан.
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2013, 15:59 16
Только учитывайте, что это достаточный резерв для данного файла, для большего нужно больше резервировать, а лучше сразу с запасом.
0
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 + все псевдосимволы
Вдруг кому-то пригодится.
0
08.06.2013, 16:04
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.06.2013, 16:04
Помогаю со студенческими работами здесь

Заменить максимальный элемент изначального вектора на первый минимальный элемент изначального вектора
Здравствуйте, помогите составить программу по обработке вектора в Mathcad 15. Необходимо вектор из...

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

Вывести элемент вектора на пересечении двух элементов этого вектора
Есть 2 переменных Rwork и uр.р, где Rworkпринимает значения от 1 до 3 с шагом 1, а uр.р от 1 до 9 с...

Найти произведение максимального элемента вектора X на минимальный элемент вектора Y.
Задать вектор X, элементы которого представляют собой арифметическую последовательность от pi/16 ...

Определить количество положительных элементов вектора С(10) и заменить этим значением минимальный элемент вектора А(5)
Ребята помогите пожалуйста с задачкой. Я сам не шарю в C++, но в этом семестре появился этот...

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


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru