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

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

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

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

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

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

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

Передача вектора в функцию по указателю - C++
Есть функция с таким прототипом: void Split(const string& text, char delimeter, const vector<string>* pPars); как воспользоваться...

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

Передача вектора списков в функцию и взаимодействие с ним - C++
Почему это не работает? #include <fstream> #include <vector> #include <list> using namespace std; ifstream in...

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

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

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

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

Не по теме:

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

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

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

Не по теме:

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

0
alsav22
5421 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2013, 00:01 #12

Не по теме:

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


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

Добавлено через 1 минуту
Цитата Сообщение от qpMM Посмотреть сообщение
Но это непонятное устранено (не нулевые элементы вектора свои адреса во время выполнения программы не меняют), так что решил не упоминать.
Это только больше всё запутывает.
0
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
08.06.2013, 00:04  [ТС] #13
Цитата Сообщение от alsav22 Посмотреть сообщение
Файл можете выложить, который используете в коде?
Расширение пришлось добавить - для загрузки.
0
Вложения
Тип файла: txt test.txt (7 байт, 3 просмотров)
alsav22
5421 / 4816 / 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;
}
1
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
08.06.2013, 15:46  [ТС] #15
Цитата Сообщение от alsav22 Посмотреть сообщение
C++
1
2
bytes.reserve(10); 
nodes.reserve(10);
Сработало. Большое спасибо, вопрос исчерпан.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.06.2013, 15:46
Привет! Вот еще темы с ответами:

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

Если элемент найден, то удалить его и стоящий перед ним элемент - Pascal ABC
всем привет, подскажите как сделать чтобы, чтобы удалялся перед найденым, стоящий перед ним элемент. {Сформировать массив Х,...

Если элемент найден, то удалить его и следующий за ним элемент из массива - Pascal ABC
Сформировать массив x, упорядоченный по убыванию. Определить, содержит ли он заданное число. Если элемент найден, то удалить его и...

Каждый элемент массива заменить на ближайший следующий за ним элемент за один просмотр - C (СИ)
В масcиве А размера N за один просмотр необходимо каждый элемент заменить на ближайший следующий за ним элемент, который больше его. Если...


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

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

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