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

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

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

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

08.06.2013, 01:24. Просмотров 381. Ответов 7
Метки нет (Все метки)

Здравствуйте. В соответствии с правилами создаю новую тему, хотя вопрос имеет отношение к другой проблеме в этом топике.

Ситуация следующая: имеется указатель на нулевой элемент вектора. Именно указатель, а не итератор. При изменении вектора, по всей видимости, меняется адрес этого нулевого элемента. Для ненулевых элементов такое не происходит. В моем случае (см. скриншоты) есть указатель 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;
}
0
Миниатюры
При работе с вектором изменяются адреса элементов   При работе с вектором изменяются адреса элементов   При работе с вектором изменяются адреса элементов  

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.06.2013, 01:24
Здравствуйте! Я подобрал для вас темы с ответами на вопрос При работе с вектором изменяются адреса элементов (C++):

Ошибка при работе с вектором - C++
Добрый вечер. у меня есть класс рабочего табеля, в котором есть поле вектора, в каждом элементе содержится количество рабочих часов в...

Помогите найти ошибку при работе с вектором - C++
// простой словарь список упорядоченных слов #include &quot;std_lib_facilities.h&quot; int main() { vector&lt;string&gt; words; string...

При работе с символами адрес вместо адреса иероглифы, а с символьными массивами вобще ошибки. - C++
/* 1) int a; int *b=&amp;a; cout&lt;&lt;b&lt;&lt;endl; 2) char a; char *b=&amp;a; cout&lt;&lt;b; */ Надо просто...

Почему при присваивании адреса массива не ставится знак '&' получения адреса - C++
int main() { int a = { 2, 3 }; int* b; b = a; //Почему при присваивании адреса массива не ставится знак '&amp;' получения адреса. ...

проблема - при выводе переменных, их значения изменяются - C++
Проблема в элементарном коде, после присваивания переменной `result1` значения `n+++m--`, значения `n` и `m`, тоже изменяются, что за...

Почему при компилировании программы со вторым экземпляром класса изменяются значения первого? - C++
Здравствуйте. Вопрос: почему при компилировании программы со вторым экземпляром класса изменяются значения первого? namespace SALES { ...

7
Croessmah
Эксперт CЭксперт С++
13415 / 7566 / 855
Регистрация: 27.09.2012
Сообщений: 18,618
Записей в блоге: 3
Завершенные тесты: 1
08.06.2013, 06:10 #2
После выполнения
C++
1
nodes.insert(nodes.end(), bytes.end()-2, bytes.end());
Все указатели и итераторы на элементы nodes могут стать не действительными, т.к. может произойти перевыделение памяти.

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

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

Цитата Сообщение от alsav22 Посмотреть сообщение
итераторы
С ними возникает проблема в 42 строчке кода - как проверить, инициализирован ли итератор или нет?
0
alsav22
5421 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2013, 16:56 #7
Может лучше вообще обойтись без узлов связанного списка? Использовать, например, контейнер list или deque. Хранить там структуры (без адресов).
0
qpMM
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
08.06.2013, 17:11  [ТС] #8
Цитата Сообщение от alsav22 Посмотреть сообщение
без адресов
Но с индексами? Или как? На данный момент с list (да и deque) пока еще не работал вообще.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.06.2013, 17:11
Привет! Вот еще темы с ответами:

Создать следующую программу: при наведении указателя мыши на кнопку ее координаты изменяются произвольным образом в пределах формы (кнопка убегает - C++
Создать следующую программу: при наведении указателя мыши на кнопку ее координаты изменяются произвольным образом в пределах формы (кнопка...

Объявить массив не более чем 15 элементов. Вывести обратные по модулю величины и проверить изменились ли адреса элементов этих двух массивов. - C++
Объявить массив не более чем 15 элементов. Вывести обратные по модулю величины и проверить изменились ли адреса элементов этих двух...

Адреса элементов массивов - C++
Добрый вечер. Никак не могу понять зависимость типа переменной массивов и вывода адресов. Пример: #include &lt;iostream&gt; using...

Адреса элементов структуры - C++
Помогите вывести адреса элементов структуры: Код экспериментальный, я в нем пишу все подряд, поэтому что-то может показаться странным,...


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

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

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