С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31

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

08.06.2013, 01:24. Показов 1724. Ответов 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
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.06.2013, 01:24
Ответы с готовыми решениями:

Почему изменяются поля элементов в очереди при работе с копией в массиве?
добрый вечер. стоит следующая задача: описать клас для хранения след информации, код кладельца, номер автомобиля, год выпуска, дата...

Ошибка при работе с вектором
Хочу вывести сумму всех элементов массива, но когда я начинаю компилировать проект, то мне выдает ошибку в файле vector.cpp в строке 1740. ...

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

7
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
08.06.2013, 06:10
После выполнения
C++
1
nodes.insert(nodes.end(), bytes.end()-2, bytes.end());
Все указатели и итераторы на элементы nodes могут стать не действительными, т.к. может произойти перевыделение памяти.

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

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

Цитата Сообщение от alsav22 Посмотреть сообщение
итераторы
С ними возникает проблема в 42 строчке кода - как проверить, инициализирован ли итератор или нет?
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2013, 16:56
Может лучше вообще обойтись без узлов связанного списка? Использовать, например, контейнер list или deque. Хранить там структуры (без адресов).
0
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
08.06.2013, 17:11  [ТС]
Цитата Сообщение от alsav22 Посмотреть сообщение
без адресов
Но с индексами? Или как? На данный момент с list (да и deque) пока еще не работал вообще.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.06.2013, 17:11
Помогаю со студенческими работами здесь

Выкидывает исключение при работе с вектором
Всем добрый день, не подскажете почему выкидывает исключение &quot;vector subscript out of range&quot; в строке 8 и 12? Не смог понять почему ...

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

Ошибка при работе с вектором в list. Код -1073741819
Здравствуйте. Не могу понять в чем дело. Во время выполнения программы выползают ошибки, при чем (!) каждый раз по-разному. Например, может...

Выводит на экран 4 прямоугольника разных цветов, при работе программы произвольно изменяются цвета
Написать программу, которая выводит на экран 4 прямоугольника разных цветов, при работе программы произвольно изменяются цвета на экране...

При удалении записей значения полей автоматически увеличивающееся на 1 (+Autoincrement) не изменяются в оставшихся полей не изменяются
При удалении записей значения полей автоматически увеличивающееся на 1 (+Autoincrement) не изменяются в оставшихся полей не изменяются


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru