LINUX.ORG.RU

указатель на статический класс, неверный указатель

 


0

1

Допустим есть код


#include <iostream> 
class A
{
        public:
        static int i;
        static void GetA(const int* a)
        {
                a = &i;
        }
};

int A::i=1;

int main() 
{
        const int *p;
        A::GetA(p);
        std::cout << *p << std::endl;
        std::cout << A::i << std::endl;
        return 0;
}


Выдается

1547644
1
Я так понимаю, что нельзя так получать указатель на статический член? Тыкните пожалуйста в пункт стандарта, где это описанно. Спасибо.

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

★★★★★

Последнее исправление: Dudraug (всего исправлений: 4)

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

#include <iostream>

class A
{
public:
    static int i;

    static void GetA(const int **p)
    {
        *p = &i;
    }
};

int A::i = 1;

int main()
{
    const int *p;
    A::GetA(&p);
    std::cout << *p << std::endl;
    std::cout << A::i << std::endl;
}
theNamelessOne ★★★★★
()

static void GetA(const int*& a)

Пукнт не знаю, ищи на тему «передача параметров по ссылке» и чем оно отличается от передачи по значению

Vinick ★★
()
Ответ на: комментарий от theNamelessOne

Ты забыл, что в методе ты работаешь с копией указателя, которая удаляется при возврате из функции

Ну т.е. как если бы ты удивлялся, что этот код не выводит 1:

#include <iostream>

void foo(int i)
{
    i = 1;
}

int main()
{
    int i = 100500;
    foo(i);
    std::cout << i << std::endl;
}
theNamelessOne ★★★★★
()

Про указатели на указатели уже писали? Срочно принять пару литров K&R и не трогать C++, пока C не переварится.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от theNamelessOne

Черт, дебильная ошибка. Спасибо.

Dudraug ★★★★★
() автор топика
Ответ на: комментарий от Vinick

Пукнт не знаю, ищи на тему «передача параметров по ссылке» и чем оно отличается от передачи по значению

Да знаю я чем отличается. Затупил, невниательность - одна из моих главных бед по жизни, плюс усталость, спасибо.

Dudraug ★★★★★
() автор топика
Ответ на: комментарий от theNamelessOne

Да я понял уже, сам ни раз работал с указателями на указатель, а тут тупо усталость - всю неделю по 12 часов в день работаю, элементарные вещи стал забывать=(

Dudraug ★★★★★
() автор топика
Ответ на: комментарий от DELIRIUM

Срочно принять пару литров K&R и не трогать C++, пока C не переварится

Дело в том, что Си++ я знаю достаточно хорошо, а это проблема в топике - это тупняк и усталость, я всегда это знал и помнил. На работе сроки горят - не сплю почти.

Dudraug ★★★★★
() автор топика
Ответ на: комментарий от Dudraug

Дело в том, что Си++ я знаю достаточно хорошо

отлично, хоть кто-то знает, а то я только знал Александревску, Саттера, Страуструпа и бустовскую банду

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от Boy_from_Jungle

отлично, хоть кто-то знает, а то я только знал Александревску, Саттера, Страуструпа и бустовскую банду

Чтоа? Что сказать то хотел?

Dudraug ★★★★★
() автор топика

Говнокод в плане «ты хочешь странного», да еще и детские ошибки при работе с аргументами и указателями. Не обманывай себя, ты не знаешь C++.

anonymous
()
Ответ на: комментарий от anonymous

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

Dudraug ★★★★★
() автор топика
Ответ на: комментарий от KennyMinigun

Не, тут лучше указатель на указатель. В реальном коде где это использвется немного иначе все.

static int GetA(const std::list<ObjT>** a)

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

Dudraug ★★★★★
() автор топика
Ответ на: комментарий от anonymous

И да, ничего странного. Банально существует список, он должен быть единственным на всю программу, хранит список пользователей, заполняется из файла при старте программы. Нужно огранизовать функции доступа к нему по определенным требованиям (там все дейсвия в ТЗ определены). Одна из такиф функций - получить список всех пользователей. Ну собственно вот. Функция возваращает код ошибки, а в параметрах указатель на статический приватный std::list.

Алсо посмотрю на тебя, когда у тебя на проекте будет ситуация, что проектный бюджет уже кончился (ну или скоро кончится), работаешь ты по 12 часов в день, а конца и края проекту еще не видно. Посмотрим на твои детские ошибки. Хорошо.

Dudraug ★★★★★
() автор топика
Ответ на: комментарий от Dudraug

Алсо посмотрю на тебя, когда у тебя на проекте будет ситуация, что проектный бюджет уже кончился (ну или скоро кончится), работаешь ты по 12 часов в день, а конца и края проекту еще не видно. Посмотрим на твои детские ошибки.

А это взрослая ошибка.

Не, тут лучше указатель на указатель. В реальном коде где это использвется немного иначе все.

static int GetA(const std::list<ObjT>** a)

Единственный use-case для указателя на указатель, который вижу я - это возможность передать NULL. Но в силу написанного выше, я не думаю, что он используется.

static int GetA(const std::list<ObjT> **a) {
    if ( a == NULL ) // хорошо бы проверить на NULL перед использованием
        return ERROR_CODE;
 
    if ( *a == NULL )
        *a = new std::vector<ObjT>();

    (*a)->push_back(something); // уродливая конструкция
    // ...
}

/* против */

static int GetA(const std::list<ObjT> *&a) {
    // не надо 2 раза проверять на NULL
    if ( a == NULL )
        a = new std::vector<ObjT>();

    a->push_back(something); // смотрится вполне неплохо
    // ...
}

Однако ребята из гугла считают, что указатель на указатель таки очевиднее.

KennyMinigun ★★★★★
()
Ответ на: комментарий от Dudraug

работаешь ты по 12 часов в день

При потоке так и работаю, очень доставляет, усталости не чувствую.

anonymous
()
Ответ на: комментарий от KennyMinigun

А это взрослая ошибка.

Так никто и не отрицает, заметь, что она детская и дебильная.

Dudraug ★★★★★
() автор топика
Ответ на: комментарий от anonymous

При потоке так и работаю, очень доставляет, усталости не чувствую.

Ну я, извини, чувствую, так вышло.

Dudraug ★★★★★
() автор топика
Ответ на: комментарий от KennyMinigun

Единственный use-case для указателя на указатель, который вижу я - это возможность передать NULL. Но в силу написанного выше, я не думаю, что он используется.

Там просто реализация некоторого сетевого протокола и теоретически может появится дполнительная логика. Поэтому лучше оставить возможность для возврата ошибки, ибо если она не нужна сейчас (а она реально сейчас при этом запросе невозможна), то не факт, что не потребность в доп. логике не появится через день другой. Поэтому сделаю указатель на указатель, ибо изначально я именно этот смысл и вкладывал, но таки да, детская и тупая ошибка. Я сам себя корю за нее, но ошибки даже глупые иногда встречаются. Извините если отнял время.

Dudraug ★★★★★
() автор топика
Последнее исправление: Dudraug (всего исправлений: 1)
Ответ на: комментарий от KennyMinigun

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

vzzo ★★★
()
Ответ на: комментарий от vzzo

Да-да, я знаю, внизу, по этому поводу небольшая фраза ;)

KennyMinigun ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.