Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.90/30: Рейтинг темы: голосов - 30, средняя оценка - 4.90
1 / 1 / 0
Регистрация: 17.04.2018
Сообщений: 26

Проблемы с указателями

31.05.2022, 02:03. Показов 6260. Ответов 64

Студворк — интернет-сервис помощи студентам
Есть вот такой код:

C++
1
2
3
4
5
6
int main 
    {
        int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int *p1 = arr, *p2 = arr + 4;
        cout << p2 + p1;
    }
1) Я не понимаю почему это выражение не выводит адрес? Ведь p2 и p1 не разыменованы?
2) Почему не получается складывать p2 и p1? При сложении у меня выходит ошибка, а при вычитании все в порядке.
3) И что еще я не могу понять, так это почему при выражении p1 - p2 выходит отрицательное число?

Для меня в теме указателей это 3 не понятных момента. В особенности я не пойму почему мы не разыменовываем все это. Как при таком подходе получается целое число а не 16-тиричное число?
Вот например есть код.

C++
1
2
3
int a = 2;
int *b = a;
cout << *a;
тут мы получим целое число только разыменовав переменную a. А в случае выше все как-то само происходит.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
31.05.2022, 02:03
Ответы с готовыми решениями:

Проблемы с указателями
Никак не могу исправить ошибки: 1) &quot;void push_back(char,int,char)&quot;: невозможно преобразовать аргумент 1 из &quot;char *&quot; в...

Проблемы с указателями
Всем привет! Нужна Ваша помощь. Есть задачка - написать функцию, которая принимает строку в качестве аргумента и удаляет из этой строки все...

Новая видеокарта, новые проблемы №2. Проблемы с вводом и выводом звуков
После покупки более новой видеокарты и последующего подключения ее через hdmi кабель, на компьютере полностью пропал звук через заднюю и...

64
Нарушающий
417 / 305 / 46
Регистрация: 13.04.2022
Сообщений: 1,759
31.05.2022, 22:28
Студворк — интернет-сервис помощи студентам
Dante20171, головоломки любите?

int i = Sizeof('X')["why not"+3];

Добавлено через 23 минуты
По поводу ++х l-value: это решил ещё Andy Koenig, для с++98.

Причина - чтобы результат присваивания можно было передавать по НЕ-const ссылке.
Поскольку ++х является результатом присваивания, он должен быть l-value

Позже это помогло с итераторами.
0
1 / 1 / 0
Регистрация: 17.04.2018
Сообщений: 26
01.06.2022, 01:54  [ТС]
Цитата Сообщение от QueryMonkey Посмотреть сообщение
int i = Sizeof('X')["why not"+3];
Ну то что X = 1 байту это понятно. А вот почему компилятор на ошибку в синтаксисе не реагирует, вот это меня удивляет. Как он допускает дополнительные надписи в квадратных скобках?)
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
01.06.2022, 05:19
Цитата Сообщение от QueryMonkey Посмотреть сообщение
int i = Sizeof('X')["why not"+3];
Что такое Sizeof? В этом и заключается головоломка?

Цитата Сообщение от Dante20171 Посмотреть сообщение
Как он допускает дополнительные надписи в квадратных скобках?)
Что такое "дополнительные надписи" и чем они отличаются от "не дополнительных"?

Добавлено через 32 минуты
Цитата Сообщение от SmallEvil Посмотреть сообщение
Можно, абстрактно
У нас есть только 9 єтажей, я хочу представить себе 18-єтажный дом.
Я взял и сложил 9 + 9 этажей, и Петя со своим "нельзя", не сможет такое представить
Это потому, что вы, как и Маша, не понимаете разницы между кардинальными и ординальными величинами (то есть количественными и порядковыми). По каковой причине Пете соврешенно понятно, что складывать два 9-тиэтажных дома можно (этажность дома - кардиналная величина), а вот складвать то, что Витя и Ира живут на девятом этаже - нельзя (адреса - ординалные величины).

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

Добавлено через 1 минуту
Цитата Сообщение от QueryMonkey Посмотреть сообщение
По поводу ++х l-value: это решил ещё Andy Koenig, для с++98.
Сслыка есть?

Цитата Сообщение от QueryMonkey Посмотреть сообщение
Причина - чтобы результат присваивания можно было передавать по НЕ-const ссылке.
Зачем и куда нужно было результат присваивания передавать по НЕ-const ссылке?

Цитата Сообщение от QueryMonkey Посмотреть сообщение
Позже это помогло с итераторами.
Как?
0
Нарушающий
417 / 305 / 46
Регистрация: 13.04.2022
Сообщений: 1,759
01.06.2022, 06:49
TheCalligrapher, посмотрите тут например

https://stackoverflow.com/ques... rns-an-lva

Насколько я вижу, это обсуждалось и возможность передать по не-конст считалась важной.

Теперь можно что-то вроде

(cmyout = cout) << "hello world\n";

написать, или

(++p)->reset();

или

delete &++x;
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
01.06.2022, 07:29
Цитата Сообщение от QueryMonkey Посмотреть сообщение
Теперь можно что-то вроде

(cmyout = cout) << "hello world\n";
Допустим... Но это настольоко частный пример, что приводит его в качестве прчины странно.

Цитата Сообщение от QueryMonkey Посмотреть сообщение
(++p)->reset();
Этот пример совсем мимо кассы. Здесь не нужна даже ссылочность результата, не говоря уже о неконстантности.

Цитата Сообщение от QueryMonkey Посмотреть сообщение
или

delete &++x;
А здесь неконстантность не нужна. delete - это константная операция. Не говоря уже о том, что delete на именнованный объект - странная затея.
0
Нарушающий
417 / 305 / 46
Регистрация: 13.04.2022
Сообщений: 1,759
01.06.2022, 08:15
TheCalligrapher, вы думаете интегральными типами, или объектами с++?

Я привел примеры где перегруженные друг-функции (у которых первый параметр type&) могут использовать ++х, когда тот l-value.

Для встроенных это вряд ли полезно

Добавлено через 20 минут
> delete - это константная операция

Почему вы так думаете? Ее вызов приводит к разрушению объекта, константные операции не изменяют свойства объекта.

Delete (const type*)(new type);

> delete на именнованный объект - странная затея.

Отнюдь. Когда параметр подаётся как не-const reference, т.е. часто
Мы как раз про это и разговариваем.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
01.06.2022, 09:50
Цитата Сообщение от QueryMonkey Посмотреть сообщение
TheCalligrapher, вы думаете интегральными типами, или объектами с++?

Я привел примеры где перегруженные друг-функции (у которых первый параметр type&) могут использовать ++х, когда тот l-value.
Не совсем понятно, о чем идет речь.

Цитата Сообщение от QueryMonkey Посмотреть сообщение
> delete - это константная операция

Почему вы так думаете? Ее вызов приводит к разрушению объекта, константные операции не изменяют свойства объекта.
Потому что константные объекты тоже нужно иметь возможность уничтожать. delete - особая операция. Константность в С++ не предполагает неуничтожимосить

C++
1
2
const std::string *const s = new const std::string;
delete s;
Цитата Сообщение от QueryMonkey Посмотреть сообщение
Delete (const type*)(new type);
???

Цитата Сообщение от QueryMonkey Посмотреть сообщение
> delete на именнованный объект - странная затея.

Отнюдь. Когда параметр подаётся как не-const reference, т.е. часто
Мы как раз про это и разговариваем.
Ничего не понял. delete принимает указатель по значению. Ей все равно, является ли параметр reference или нет.

И, еще раз, я не могу себе представить (кроме искусственных извращений), где delete было бы осмысленно применять для уничтожения именованного объекта. То есть delete &x оправданно разве что в

C++
1
2
std::string &x = *new std::string;
delete &x;
Но это извращение.
0
12 / 10 / 2
Регистрация: 24.05.2022
Сообщений: 115
01.06.2022, 10:26
Учились Маша и Петя в Универе, Маша и Петя были очень умными учениками, но Петя был лентяй и иногда прогуливал лекции. И вот пришло время экзамена, Маша справилось со своим задание и получила пятерку. Петя тоже сделал свое задание на отлично, но препод отказывался ему ставить 5, он же прогульщик и лентяй, но Петя все унимался и требовал поставить ему пятёрку. Когда препод разозлился, он решил наказать Петю задав ему решить одну формулу.
Когда Маша увидела эту формулу, она улыбнулась и ушла, она же поняла, что эту формулу не имеет решения, т.к. это было аж целое занятие посвящено этой формуле, а Петя как раз прогулял этот день и не знал, что это не возможно решить.
И вот Петя садится за стол и пытается ее решить, проходит час, два, три, четыре. Уже остался последний ученик на экзамене.
И тут Петя начинает улыбаться во все свои 32.
Отдает решение преподавателю у которого, глаза стали по 5 копеек.
Он начинает лепетать. - этого не возможно, это не возможно.
Тут Петя спрашивает. - что не возможно?
- это не возможно было решить!!!
Ответ Пети.
- Простите я этого не знал.
0
Нарушающий
417 / 305 / 46
Регистрация: 13.04.2022
Сообщений: 1,759
01.06.2022, 16:42
TheCalligrapher, лучше наверное посмотрите по ссылке, может их примеры вам больше понравятся.

Bjorn Stroustrup и его коллеги ещё живы, можете написать и напрямик и спросить что они думали.

Потому что константные объекты тоже нужно иметь возможность уничтожать. delete - особая операция. Константность в С++ не предполагает неуничтожимосить
С вами совершенно не согласен по этому пункту.
Я считаю что:
- delete не является const функцией. Т.к. она разрушает объект и ее параметр задекларирован как "void *", а не "const void *"
- константные объекты нет возможности уничтожать через delete. Тут важно понимать что const указатель на объект не делает сам объект const, только интерфейс к нему через этот указатель.

Мы отошли от вопроса ТС, но поскольку обсуждаем указатели предлагаю не считать офтопом,особенно если другим интересно.
0
531 / 180 / 39
Регистрация: 18.08.2012
Сообщений: 907
01.06.2022, 18:24
Складывать 2 указателя нельзя по той причине, что это:
  • вызовет ошибку компилятора (защита от дурака)
  • потому что тогда сумма указателей будет указывать в "космос".
    как пример: размер памяти = 10,
    указатель1 = 9
    указатель2 = 8
    сумма = либо ошибка переполнения, либо ошибка доступа к памяти
Однако,
сам компилятор, при включенной оптимизации запросто складывает 2 указателя.
Таким образом,
правила о запрете сложения двух указателей - касаются/распространяются только на программиста.
0
01.06.2022, 18:29

Не по теме:

Цитата Сообщение от QueryMonkey Посмотреть сообщение
а сумма потенциалов не бывает.
внезапно:
Кликните здесь для просмотра всего текста

0
Нарушающий
417 / 305 / 46
Регистрация: 13.04.2022
Сообщений: 1,759
01.06.2022, 18:35
Лол, да я увлекся с примерами. Главное чтобы суть была понятна.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
01.06.2022, 20:54
Цитата Сообщение от QueryMonkey Посмотреть сообщение
delete не является const функцией.
delete - это не функция.

Цитата Сообщение от QueryMonkey Посмотреть сообщение
ее параметр задекларирован как "void *", а не "const void *"
Таким образом параметр "задекларирован" у operator delete, а не у delete. Вот operator delete как раз функция.
Но к ней дело переходит уже после разрушения объекта, т.е. operator delete вообще не имеет дела с объектами, а только с памятью. Константный объект был или нет, память тут (уже) не при чем, поэтому там и нет const void*.

Цитата Сообщение от QueryMonkey Посмотреть сообщение
константные объекты нет возможности уничтожать через delete.
Он же выше привел пример создания и уничтожения константного объекта. Что значит "нет возможности"?

Цитата Сообщение от QueryMonkey Посмотреть сообщение
Тут важно понимать что const указатель на объект не делает сам объект const, только интерфейс к нему через этот указатель.
В его примере не "const указатель на объект делает сам объект const" (кому вообще такое могло прийти в голову? никто тут такого не утверждал). В его примере изначально константный объект созданный в динамической памяти адресуется через указатель на const. Т.е. ситуация противоположная.

В общем, насчет константности delete, я думаю, все еще можно поспорить, но не с такими аргументами как у вас.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
01.06.2022, 21:21
Цитата Сообщение от QueryMonkey Посмотреть сообщение
С вами совершенно не согласен по этому пункту.
Это не вопрос вашего согласия или не согласия. Это жесткие факты, которые просто нужно знать.

Цитата Сообщение от QueryMonkey Посмотреть сообщение
Я считаю что:
- delete не является const функцией. Т.к. она разрушает объект и ее параметр задекларирован как "void *", а не "const void *"
Во-первых, сразу даю под запись: в вопросах создания и уничтожения объектов понятия "константности" не существует вообще. Создания и уничтожение - это концепции существенно более высокого уровня, чем константность. Константность объекта никак не препятствует созданию или уничтожению объекта. Да и не должна, с точки зрения банального здравого смысла.

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

Во-вторых, о какой "функции delete" вы вообще ведете речь? Какой void *? delete - это оператор языка, а никакая не функция. Никакого void * она не принимает. void * там даже близко нет. О чем вы?

Цитата Сообщение от QueryMonkey Посмотреть сообщение
- константные объекты нет возможности уничтожать через delete. Тут важно понимать что const указатель на объект не делает сам объект const, только интерфейс к нему через этот указатель.
Что за чушь? Я только что привел пример создания и удаления константного объекта.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.06.2022, 21:59
Цитата Сообщение от QueryMonkey Посмотреть сообщение
Я считаю что:
- delete не является const функцией. Т.к. она разрушает объект и ее параметр задекларирован как "void *", а не "const void *"
во-первых, нужно различать оператор delete, и выражение delete.
оператор работает с памятью, когда объект уже разрушен.

а вот выражение delete сначала вызывает деструктор,
и только после этого освобождает память.

время жизни объекта завершается по факту завершения работы его деструктора.
таким образом, рассуждая в твоих категориях,
получается, что объект разрушает "функция деструктора",
а вовсе не "функция delete"

а во-вторых:
на этапе работы конструктора или деструктора,
понятия "константности *this" не существует.

поэтому, следующий код успешно компилируется:

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
#include <iostream>
 
struct some
{
    void ctor() 
    { 
        std::cout << "на этапе работы конструктора "
            "можно запускать не константные методы "
            "даже для константных объектов\n";
    }
    void dtor()
    { 
        std::cout << "на этапе работы деструктора "
            "можно запускать не константные методы "
            "даже для константных объектов\n";
    }
    some() { ctor(); }
   ~some() { dtor(); }
};
 
int main()
{
    const some obj;
    (void) obj;
}
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
01.06.2022, 22:28
Не могу пройти мимо и не запостить самый популярный, на мой взгляд, косяк в геймдеве -- освобождение памяти чужого объекта.
Причём работает, даже если он константный по самое ненадейся.

Синтетический пример:
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
#include <iostream>
class B {
public:
    ~B() {
        std::cout << "I am doing something awful!" << std::endl;
    }
};
 
class A {
public:
    A() : data(new B{}) {
    }
    ~A() {
        delete data;
    }
    const B * const data;
};
 
int main() {
 
    const A a;
 
    delete a.data;
 
    return 0;
}
Мораль 1: делету пофиг на константность, потому что он освобождает память по адресу.
Мораль 2: создал -- не забудь удалить. не создавал -- не удаляй.
0
Нарушающий
417 / 305 / 46
Регистрация: 13.04.2022
Сообщений: 1,759
01.06.2022, 22:37
TheCalligrapher, hoggy, я заблуждался насчёт delete.

Для него действительно сделали исключение в стандарте с++ как минимум 20 лет назад.

Msvc и с++ от борланда (тогда) запрещали delete константных указателей,
что логично для их девелопера и для меня, но стандарт есть стандарт.

Мой g++ правильно следует стандарту, из-за чего возможны глупости вроде

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void foo( const int &i )
{ delete &i; }
..
 
int* p = new int;
 
foo( *p ); // ok
...
foo( ++*p ); // ok, если вместо предыдущего 
...
foo( (*p)++ ); // heap fault
...
foo( 5 ); // heap fault
В "сломанном" msvc/turbo такой косяк был бы пойман на стадии компиляции.
Это неудачное решение, позволить прятать удаление объектов внутри функций задекларированеых "сонст".
Наверное, была всякая причина.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
01.06.2022, 22:55
Цитата Сообщение от QueryMonkey Посмотреть сообщение
Мой g++ правильно следует стандарту, из-за чего возможны глупости вроде
Ничего не понял. Какое отношение тема применения delete к неправильным указателям имеет к теме константности??? Все ваши "глупости" можно прекрасно стопроцентно воспроизвести и без константности. То есть константность к вашим примерам никакого отношения не имеет вообще.

Цитата Сообщение от QueryMonkey Посмотреть сообщение
Наверное, была всякая причина.
Тему, которую я уже полностью закрыл выше: не существует и никогда не существовало понятия "константности" в вопросах создания и удаления объектов. Это следует из банального и очевидного здравого смысла.
0
Нарушающий
417 / 305 / 46
Регистрация: 13.04.2022
Сообщений: 1,759
02.06.2022, 06:17
TheCalligrapher, > Ничего не понял.

Я могу объяснить более подробно.

Добавлено через 4 часа 36 минут
Забавно: E2158 Operand of 'delete' must be non-const pointer (C++)

Добавлено через 12 минут
Курьезно: Error message in Visual C++ when you delete a pointer to a const object
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
02.06.2022, 06:34
Цитата Сообщение от QueryMonkey Посмотреть сообщение
Добавлено через 4 часа 36 минут
Забавно: E2158 Operand of 'delete' must be non-const pointer (C++)

Добавлено через 12 минут
Курьезно: Error message in Visual C++ when you delete a pointer to a const object
И? Вы же уже упоминали эти баги в старинных версиях MSVC++ и пр. компиляторах ранее. В былые времена в них столько багов было - закачаешься...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.06.2022, 06:34

Проблемы с инетом, не отправляется почта, проблемы со связью с другой организацией
Здравствуйте. Есть проблемка. Такая ситуация - Организация. Компьютеры подключены по локалке. Находятся в домене. Интернет есть, но! не...

Yokogawa, шкаф, проблемы с драйвером на станции, проблемы соединения
Доброго времени суток, есть шкаф вот с таким оборудованием: Шкаф подключен к станции под управлением двух ос. Обе...

Непонятка с указателями
У меня есть типизированный файл, из которого нужно удалить запись. Я все данные сую в динам массив и затем перезаписываю файл с этого...

Работа с указателями
Доброго времени суток! Прошу помощи в решении очень интересной задачи. Перепробовал все свои знания., не получается( Чаще всего...

Массивы с указателями
Здравствуйте, помогите написать программу. Переписать сначала отрицательные, а затем положительные элементы массива BC, содержащего N...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Многофункциональное здание: как одно здание порождает конфликты требований, которые никто не планировал (мат мет мод 29)
anaschu 23.06.2026
Многофункциональное здание: как одно здание порождает конфликты требований, которые никто не планировал Материалы для обсуждения с МГСУ · 2026 Рисунки внутри приложенного ворд файла. Что за. . .
28. Конкретное развертывание плана номер 1 из поста номер 27
anaschu 22.06.2026
Можно ли из модели получить конкретные строительные требования? Честно — напрямую из текущей модели такие ответы не получить. Но цепочка логики есть, и она не такая длинная. Где разрыв . . .
27. Планы на разработку функциональных требований к строительству внутри модели пищеблока (или не только его?)
anaschu 22.06.2026
Что уже реализовано и даёт конфликты «бесплатно» Самый простой конфликт уже работает — конфликт за ресурс-работника. Заданий больше, чем доступных поваров → очередь в queue1. Это прямое отражение. . .
26. мед мат модель.Какие типы конфликтов функциональных требований можно рассчитать через ДЕС-моделирование (СМО) в AnyLogic?
anaschu 22.06.2026
Что ДЕС/ СМО умеет считать напрямую: Конфликты за ресурсы (очереди, узкие места). Несколько типов агентов (повара, учителя, рабочие, пациенты) претендуют на один ресурс (лифт, вход, коридор,. . .
25 модель здравосохранения и функциональных требований к пищеблоку: конфликты функциональных требований.
anaschu 22.06.2026
Есть ли данные о том, какие функциональные/ эксплуатационные требования или их сочетания труднее всего учитывать при проектировании зданий? Да, такие данные есть, и они хорошо описаны и в российской,. . .
Remote Connection Manager
DevAlt 21.06.2026
Написал для себя небольшую прилагу: https:/ / github. com/ altbodhi/ ReConMan По итогу пришел к мысли, что DU не дружат с существующими технологиями. От сериализации до отображения в реляционную. . .
Администрация Хабра удаляет новые энрегоэфективные алгоритмы, которые не западной школы кода, и вовсе никак не сгенерировавны.
Hrethgir 20.06.2026
Делается это, как замечено, при правках - при объявлении концептуальных отличий в алгоримах. Делается это, по линейке событий - после дополнения публикации основными отличиями от основных западных. . .
Процесс ориентированная диалектика (не новость - просто системное обновление, философия).
Hrethgir 20.06.2026
Однажды один участник в своём блоге, на этом форуме, сделал запись "О языках замолвите слово". Понимая, что язык - важная вещь, я решил хорошо подумать, прежде чем сказать, и сказал то, что вы видите. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru