C ++ Получение адреса временного - ошибка при назначении ссылки на указатель - PullRequest
1 голос
/ 13 февраля 2012

Эта программа написана на C ++. Я пытаюсь использовать функцию void для расширения структуры Line, которая состоит из целочисленной длины и указателя на следующую подключенную строку. Существует функция void Expand, созданная для назначения ссылки на строку указателю на строку в структуре. Новая строка должна быть в два раза больше текущей строки. С кодом, который я использую, я получаю ошибку g ++ «Взятие адреса временного [-fpermissive]». Может ли кто-нибудь предложить способ, которым функция добавляет действительный экземпляр ссылки на строку в указатель строки nextLine?

struct Line
{
    int length;
    Line* nextLine;
};

Line NewLine(Line& lineRef)
{
    Line newLine;
    newLine.length = lineRef.length * 2;
    return newLine;
}

void Expand(Line& lineRef)
{
    //Error here states: Taking address of temporary [-fpermissive]
    lineRef.nextLine = &NewLine(lineRef);
}

int main() {

    Line line;

    Expand(line);

    cout << line.length << endl;
    cout << line.nextLine->length << endl;

    return 0;
}

Ответы [ 3 ]

3 голосов
/ 13 февраля 2012

Вы пытаетесь реализовать связанный список, но пока не понимаете ручное управление памятью.

Краткосрочным решением является использование std::list<Line>. Уже есть решение, которое работает, и вам не нужно беспокоиться о закулисных вещах.

Долгосрочным решением также является использование std::list<Line>. Не нужно заново изобретать колесо, даже если вы опытный разработчик и умеете.

3 голосов
/ 13 февраля 2012

Проблема со строкой:

lineRef.nextLine = &NewLine(lineRef);

- это то, что говорит вам компилятор.Вы берете временный адрес.Это означает, что после достижения ; временный NewLine(lineRef) будет уничтожен, а указатель lineRef.nextLine будет указателем на мертвый объект.


Обновление: как сделать эторабота.

Это зависит от того, что вы хотите сделать.Если вам нужно иметь список , то самое простое - использовать предварительно упакованную структуру данных list (std::list<Line>), а не использовать собственную реализацию списка.

Если вы действительно хотите реализовать свой собственный список, то вам нужно будет динамически выделить следующий узел (это сделает компилятор счастливым), и вам нужно будет добавить код для управления list (правильная конструкция Line объекта, который инициализирует поля, включая copy-construction , деструкторы для управления динамической памятью, возможно, некоторые вспомогательные функции для walk списка (или итераторов , чтобы иметь возможность использовать алгоритмы ...) Просто не беспокойтесь и используйте std::list.

1 голос
/ 13 февраля 2012

Это работает

    struct Line
    {
            int length;
            Line* nextLine;
            ~Line(){delete nextLine;}
             //Make copy constructor and assignment operator private
    };

    void Expand(Line* lineRef)
    {
            lineRef->nextLine = new Line;
            lineRef->nextLine->length = 2*(lineRef->length) ;
    }

int main() 
{

        Line* line = new Line;
        line->length = 5;

        Expand(line);

        cout << line->length << endl;
        cout << line->nextLine->length << endl;

        delete line;
        return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...