0 / 0 / 0
Регистрация: 19.02.2018
Сообщений: 7

Адрес элемента в векторе

19.02.2018, 18:51. Показов 8207. Ответов 29

Студворк — интернет-сервис помощи студентам
привет всем!

есть код
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <vector>
 
int main()
{
    std::vector<int> v = { 1, 2, 3, 4, 5 };
    
    std::cout << &v[0] + 2 << std::endl;
    std::cout << &v[2]     << std::endl;
}
он выводит например
0x19abc28
0x19abc28

подскожите всегдали вывод во второй строке будет такой же как в первой7
число элементов в векторе больше либо равно три конечно же!
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.02.2018, 18:51
Ответы с готовыми решениями:

Убедиться, что адрес первого элемента массива и адрес, хранящийся в указатели на этот массив равны.
Убедиться, что адрес первого элемента массива и адрес, хранящийся в указатели на этот массив - равны.

Поиск самого большого элемента в векторе
Здравствуйте. Такой вот не сильно сложный вопрос: Как найти в vector&lt;int&gt;v самое большое число ? Я могу написать &quot;велосипед&quot;,...

Ошибка в поиске максимального и минимального элемента в векторе
#include &lt;iostream&gt; #include &lt;qdebug.h&gt; #include &lt;vector&gt; using namespace std; int main() { ...

29
1 / 1 / 0
Регистрация: 20.02.2018
Сообщений: 6
21.02.2018, 01:53
Студворк — интернет-сервис помощи студентам
Croessmah, ну я же честно написал:
Цитата Сообщение от Друг ньюфага Посмотреть сообщение
Я бы сам никогда не догадался, если бы не прочитал у умных людей
Скажу ещё прямее: я подобрал тему на околокомитетской помойке (хоть и открытый мейл-лист, но там тусуются люди из комитета).

Реализовать std::vector в текущей модели памяти C++ без UB невозможно. Доказывать мне обратное бессмысленно, т.к. это не моё мнение. Да, я буду давить авторитетом.

Хотя желание поспорить понятно. Многим неуютно, когда идиоматический код оказывается нагромождением UB. Поэтому модель памяти собираются пропатчить так, что можно будет реализовать вектор с этой гарантией "непрерывности".

Цитата Сообщение от Croessmah Посмотреть сообщение
т.е. array object не обязан быть object of array type.
Если полазать по стандарту, то видно, что "array object" называют именно массивы.

Цитата Сообщение от Croessmah Посмотреть сообщение
new-expression может выделять array object, но при этом возвращает указатель не на array type.
Ну, за что Страуструпу надо оторвать яйца, можно лишний раз не напоминать.

Кстати, забавно:
Кликните здесь для просмотра всего текста
Про new сказано:
If it is an array, the new-expression returns a pointer to the initial element of the array.
А про массивы и их первые элементы сказано:
If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_cast (8.2.10). [ Note: An array object and its first element are not pointer-interconvertible, even though they have the same address. — end note ]
Интересно, как это понимать? Адрес, который вернул new-expression при выделении массива, нельзя использовать как адрес массива? Лол!


Цитата Сообщение от Croessmah Посмотреть сообщение
т.е. указатель на одиночный объект будет вести себя так, как будто он является указателем на первый элемент массива с размером 1.
Именно поэтому в коде написано &v[0] + 2
Чтобы нельзя было сослаться на это место.

Про new мне позволю себе подробно не разбирать. Отвечу так: когда в C вводили правило strict aliasing-а, возникла проблема: malloc принимает только размер и возвращает void*, какой же тип выделяет malloc, чтобы можно было кастануть этот void* и пользоваться памятью через типизированный указатель не нарушая strict aliasing-а? Решение было примерно таким: память под какой тип программист намеревался выделить, на кусок памяти такого типа malloc и возвращает указатель. malloc — это волшебная функция.
new это тоже волшебное выражение. У него особая роль в C++ — оно может создавать объекты. Даже если new[] сделан через new(size), то выделяется массив. Почему? Магия.
Если в стандарте кривоватые формулировки по поводу new (типа как под спойлером), их можно поправить.

А вот для работы вектора без UB нужно вносить правки серьёзнее исправления формулировок.

Добавлено через 40 минут
Цитата Сообщение от Croessmah Посмотреть сообщение
Т.е. адресация между его началом и концом будет в пределах одного массива байт.
Мысль в правильном направлении. Примерно так и хотят пофиксить проблему с вектором.
Есть такая хрень, как предоставление массивом из байтов памяти под объект (http://eel.is/c++draft/basic.m... es_storage). Идея разрешить адресную арифметику для объектов, для которых один и тот же объект-массив provides storage. Но это надо фиксить пункт про оператор плюс для указателей. Плюс надо в определении new указать, что оно выделяет именно массив байт, который можно использовать чтобы provide storage. Пока что про массив там ничего не сказано, сказано про " allocate size bytes of storage".
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8217 / 5048 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
21.02.2018, 14:02
Цитата Сообщение от Друг ньюфага Посмотреть сообщение
модель памяти собираются пропатчить так, что можно будет реализовать вектор с этой гарантией "непрерывности"
Стандарт итак гарантирует непрерывность данных в векторе. В С++17 ввели понятие "contiguous". Теперь вектор "dynamic contiguous array".
0
1 / 1 / 0
Регистрация: 20.02.2018
Сообщений: 6
21.02.2018, 20:46
Цитата Сообщение от MrGluck Посмотреть сообщение
Стандарт итак гарантирует непрерывность данных в векторе
Ради бога, пусть там есть непрерывность. Только не существует реализации вектора, в котором одновременно push_back работает за амортизационное O(1) и выполняется &v[n] == &v[0] + n for all 0 <= n < v.size().
0
1719 / 568 / 187
Регистрация: 12.03.2016
Сообщений: 2,169
21.02.2018, 21:19
А мне интересно кто тут под ником Друг ньюфага, начинает развод бадяжить.
То в #4 пишем
MrGluck, New man, просто мне друг сказал что тут какое-то не определенное поведение.
я подумал это значит что не известно будет такое же значение или не будет.
Т.е. я не я, моя твоя ничего не понимай.
И смотрим #21
Где у ТС уже совсем другие познания и стиль изложения. (Даже Страуструпа кастрировать собрался).
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
22.02.2018, 02:02
Цитата Сообщение от Друг ньюфага Посмотреть сообщение
Поэтому модель памяти собираются пропатчить так, что можно будет реализовать вектор с этой гарантией "непрерывности".
Как это вообще зависит от модели памяти с тех пор когда она стала линейной (что опять же не от языка зависело а от железа)? Это зависит исключительно от модели буфера которую использует вектор - т.е. выделяет весь буфер одним куском (как обязан делать по стандарту) или использует сегментированный буфер (как могли делать реализации до внесения в стандарт нормы о хранении буфера одним куском).

Добавлено через 3 минуты
Цитата Сообщение от Друг ньюфага Посмотреть сообщение
Доказывать мне обратное бессмысленно, т.к. это не моё мнение. Да, я буду давить авторитетом.
Если бы это было ваше мнение эту тему еще возможно стоило бы обсуждать. А так это не более чем источник ОБС (Одна Бабка Сказала)

Добавлено через 12 минут
Цитата Сообщение от Croessmah Посмотреть сообщение
Речь идет не о типе массива, а о последовательно лежащих элементах, т.е. о массиве как о структуре данных.
Возможно, товарищи меня поправят, но я считаю, что Вы неправы в этом вопросе.
Я так понимаю товарисч Друг ньюфага, путает понятия "распределенная память" и "сконструированные элементы" поэтому и думает что обращение за пределы size() обязательно ведет к UB что даже в таком случае далеко не всегда так. А следовательно не понимает что никакого UB не будет если обращаться в пределах size(). Ну и при этом не понимает где чья зона ответственности - программиста или вектора за вычисление адреса элемента при разных способах обращения.

Добавлено через 13 минут
Цитата Сообщение от Друг ньюфага Посмотреть сообщение
Только не существует реализации вектора, в котором одновременно push_back работает за амортизационное O(1) и выполняется &v[n] == &v[0] + n for all 0 <= n < v.size().
Это с каких делов? Для несегментированных буферов она существовала еще когда STL не существовало. Другое дело что тогда несегментированным мог быть буфер не более 64KБ размером.
1
1 / 1 / 0
Регистрация: 20.02.2018
Сообщений: 6
22.02.2018, 02:18
Fulcrum_013, я думаю, C++ — не Ваш конёк.
Вам лучше пообсуждать уменьшение EXE-файлов с помощью замены DOS stub.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
22.02.2018, 02:28
Друг ньюфага,
Код оператора [] вектора
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    const_reference operator[](size_type _Pos) const
        {   // subscript nonmutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
        if (size() <= _Pos)
            {   // report error
            _DEBUG_ERROR("vector subscript out of range");
            _SCL_SECURE_OUT_OF_RANGE;
            }
 
 #elif _ITERATOR_DEBUG_LEVEL == 1
        _SCL_SECURE_VALIDATE_RANGE(_Pos < size());
 #endif /* _ITERATOR_DEBUG_LEVEL */
 
        return (*(this->_Myfirst() + _Pos));
        }
Внимательно смотри что именно он возвращает.
И доверять любым другим источникам (!неожиданно)не имею права по роду занятий.
0
0 / 0 / 0
Регистрация: 19.02.2018
Сообщений: 7
23.02.2018, 15:15  [ТС]
всем спасибо
все свободны
0
1 / 1 / 0
Регистрация: 20.02.2018
Сообщений: 6
23.02.2018, 15:45
Вот, если кому интересно, ссылка на сообщение от Richard Smith1
Цитата Сообщение от https://groups.google.com/a/isocpp.org/d/msg/std-discussion/p4BXNhTHY7U/ahp5CzNFQQAJ
<цитата вырезана>

You didn't specify how to implement the piece that's not implementable :-)

T *vector<T>::data() { return ??? }

vector<int> vi;
vi.push_back(1);
vi.push_back(2);
vi.push_back(3);
vi.data()[2] = 12; // ub, there is no array object on which to do array indexing

C++98's vector was fine, since it didn't pretend to expose an array to the user (there was no data(), iterators could be used to encapsulate the reinterpret_casts, and there was no contiguous iterator guarantee), but this has been unimplementable in the formal C++ object model since C++03 guaranteed that (&vi.begin())[2] should work.

Obviously it's actually fine in practice (and your implementation will certainly make sure it works), the question here is how to tweak the formal wording to give the guarantees we actually want. There are a number of different options with different tradeoffs (should we require explicit code in std::vector to create an array object? should we allow nontrivial pointer arithmetic / array indexing on pointers that don't point to arrays? should we magically conjure an array object into existence to make this work? should we allow an array object to be created without actually initializing all of its elements? how should the lifetime of an array object work anyway?). I'll probably write a paper on that once we're done with p0137.
1)
Цитата Сообщение от https://isocpp.org/std/the-committee
Project Editor: Richard Smith (Google). The project editor is the person ultimately responsible for applying committee-approved changes to the standard’s working draft.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
23.02.2018, 16:29
Друг ньюфага,
из кода вектора STL
C++
1
2
3
4
_Ty * data() _NOEXCEPT
        {   // return address of first element
        return (_Unfancy_maybe_null(this->_Myfirst()));
        }
из кода моего аналога вектора

C++
1
DataType* GetData(){return FData;} ;
Т.е. указатель на лежащие подряд единым куском данные возвращается в корректных реализациях.
Ну а то что возвернутый указатель может nullptr оказаться ну дак на то и динамический массив а не статический.

Добавлено через 5 минут
Цитата Сообщение от Друг ньюфага Посмотреть сообщение
since it didn't pretend to expose an array to the user
Которая делала вектор useless во многих делах где нужен именно RAW буфер. Например в вопросе забросить накопленные в нем вертексы в видеопамять или опять же передать его содержимое по сети как raw данные.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.02.2018, 16:29

Найти номер по порядку элемента в векторе векторов
Подскажите, пожалуйста. Например, есть vector &lt;vector&lt;int&gt; &gt; k; а мне нужно найти номер по порядку элемента (a,b) в этом векторе...

Вернуть индекс последнего с конца элемента E в векторе V
подскажите нужно сделать следующие ------find_last(v, e) - вернуть индекс элемента e в векторе v, но последний с конца---- написал вот...

Добавить методы поиска медианного элемента в матрице и векторе
Здравствуйте есть программа #include &quot;stdafx.h&quot; #include &lt;stdlib.h&gt; #include &lt;iostream&gt; #include &lt;math.h&gt; #include &lt;time.h&gt; ...

Как в векторе объектов пользовательского класса изменить заданное поле у определённого элемента?
Добрый день. Создан вектор из структры: struct man { char name; int age; man(void) {} man(const...

Присвоить указателю адрес 6-го элемента массива, напечатать его значение, используя текущий базовый адрес сегмента
Заполнить массив А(10) случайными значениями. Организовать вывод на экран. Присвоить указателю адрес начала размещения массива в памяти....


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

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

Новые блоги и статьи
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов. Логика кажется понятной: 1. Находим ключевые слова. 2. Добавляем их на. . .
Знание — сила: Доктрина интенциональности знаний, углубление в формулу
Hrethgir 01.08.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11957&stc=1&d=1785567302 Знаменитый афоризм Фрэнсиса Бэкона «Знание — сила» (Scientia potentia est) в массовой культуре принято понимать. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru