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

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

Восстановить пароль Регистрация
 
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
08.06.2013, 01:24     При работе с вектором изменяются адреса элементов #1
Здравствуйте. В соответствии с правилами создаю новую тему, хотя вопрос имеет отношение к другой проблеме в этом топике.

Ситуация следующая: имеется указатель на нулевой элемент вектора. Именно указатель, а не итератор. При изменении вектора, по всей видимости, меняется адрес этого нулевого элемента. Для ненулевых элементов такое не происходит. В моем случае (см. скриншоты) есть указатель left, содержимое памяти и ссылаемый адрес которого я пометил красной чертой. left указывает на нулевой элемент вектора bytes, к которому я тоже подвел красную черту и который, будучи являясь структурой, содержит в себе переменную oldByte типа char инициализированную латинским символом 'o'. После выполнения 109-ой строчки кода (см. ниже) содержимое памяти по адресу, на который ссылается left, неожиданно стирается (см. второй скриншот). В то время как с первым элементом вектора nodes ничего подобного не происходит: oldByte соответствующей структуры ('r') остается прежним (см. третий скриншот). Вопрос, собственно, состоит в том, почему так происходит и должно ли быть так.

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;
}
Миниатюры
При работе с вектором изменяются адреса элементов   При работе с вектором изменяются адреса элементов   При работе с вектором изменяются адреса элементов  

Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.06.2013, 01:24     При работе с вектором изменяются адреса элементов
Посмотрите здесь:

Объявить массив не более чем 15 элементов. Вывести обратные по модулю величины и проверить изменились ли адреса элементов этих двух массивов. C++
проблема - при выводе переменных, их значения изменяются C++
C++ Адреса элементов структуры
При работе с символами адрес вместо адреса иероглифы, а с символьными массивами вобще ошибки. C++
C++ Создать следующую программу: при наведении указателя мыши на кнопку ее координаты изменяются произвольным образом в пределах формы (кнопка убегает
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
08.06.2013, 06:10     При работе с вектором изменяются адреса элементов #2
После выполнения
C++
1
nodes.insert(nodes.end(), bytes.end()-2, bytes.end());
Все указатели и итераторы на элементы nodes могут стать не действительными, т.к. может произойти перевыделение памяти.

То, что в памяти еще содержаться старые данные - это лишь вопрос времени и случая
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2013, 15:28     При работе с вектором изменяются адреса элементов #3
qpMM, резервируйте память под векторы.
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
08.06.2013, 15:46  [ТС]     При работе с вектором изменяются адреса элементов #4
Цитата Сообщение от alsav22 Посмотреть сообщение
резервируйте память под векторы
Значит все-таки неправильно я воспринимал эти векторы. Казалось, что об их размере и организации памяти с ними можно вообще не беспокоиться, все автоматизировано Теперь понятно.

Croessmah, alsav22, спасибо!
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2013, 16:08     При работе с вектором изменяются адреса элементов #5
Проблема в том, что вы работаете с адресами элементов вектора. Обычное обращение к элементам вектора - итераторы или индексы. Мне кажется, что обращение по адресам - не лучшая идея.
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
08.06.2013, 16:14  [ТС]     При работе с вектором изменяются адреса элементов #6
Цитата Сообщение от alsav22 Посмотреть сообщение
не лучшая идея
Я уже это тоже понял, хочу попробовать переписать с индексами.

Цитата Сообщение от alsav22 Посмотреть сообщение
итераторы
С ними возникает проблема в 42 строчке кода - как проверить, инициализирован ли итератор или нет?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2013, 16:56     При работе с вектором изменяются адреса элементов #7
Может лучше вообще обойтись без узлов связанного списка? Использовать, например, контейнер list или deque. Хранить там структуры (без адресов).
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.06.2013, 17:11     При работе с вектором изменяются адреса элементов
Еще ссылки по теме:

C++ Помогите найти ошибку при работе с вектором
C++ Почему при компилировании программы со вторым экземпляром класса изменяются значения первого?
C++ нарушение прав доступа при исполнении при работе с C# DLL C++

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

Или воспользуйтесь поиском по форуму:
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
08.06.2013, 17:11  [ТС]     При работе с вектором изменяются адреса элементов #8
Цитата Сообщение от alsav22 Посмотреть сообщение
без адресов
Но с индексами? Или как? На данный момент с list (да и deque) пока еще не работал вообще.
Yandex
Объявления
08.06.2013, 17:11     При работе с вектором изменяются адреса элементов
Ответ Создать тему
Опции темы

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