возвращаемое значение указателя изменяется после вызова функции - PullRequest
5 голосов
/ 18 декабря 2011

Фрагменты кода из двух исходных файлов C:

A.c

Channel *testChannelGet()
{
    Channel *ch = channelGet (parser,parserCh);
    return ch;
}

B.c

Channel *channelGet(UINT8 parser, UINT16 parserCh)
{
    chnl.player = &solPlayer;
    return((Channel *)&chnl);
}

Я компилирую оба файла и создаю статическую и общую библиотеку. Теперь я вызываю testChannelGet из примера программы. Когда я связываю его со статической библиотекой, он работает отлично. Но если я связываю его с разделяемой библиотекой, это SEGFAULTing. Отладка говорит мне, что указатель, возвращенный из channelGet, изменяется с момента его возврата. Вывод GDB ниже.

174         Channel *ch = channelGet (parser,parserCh);
(gdb) s
channelGet (parser=1 '\001', parserCh=1) at B.c:15174
15174           chnl.player = &solPlayer;
(gdb) n
15175           return((Channel *)&chnl);
(gdb) p ((Channel *)&chnl)
$1 = (Channel *) 0x7ffff7fed1a0
(gdb) n
15176   }
(gdb) n
testChannelGet at A.c:175
175         return ch;
(gdb) p ch
$2 = (Channel *) 0xfffffffff7fed1a0

Кажется, значение адреса теперь указывает на другое смещение - 0xfffffffff7fed1a0 против 0x7ffff7fed1a0. Последние байты в обоих адресах одинаковы.

Есть намеки? Я пробовал опцию -fPIC безрезультатно.

Ответы [ 2 ]

5 голосов
/ 18 декабря 2011

Есть ли в области действия прототип для channelGet() в A.c?

Если нет, то результаты, которые вы видите, можно объяснить следующим образом:

  • channelGet() предполагается, что он возвращает int (из-за отсутствия прототипа), поэтому результат усекается до 0xf7fed1a0
  • , затем он приводится к 64-битному указателю, поэтому знак расширяется до 0xfffffffff7fed1a0

(Вы должны получать жалобы по этому поводу, если вы компилируете с включенными предупреждениями, конечно ...)

1 голос
/ 18 декабря 2011

Запустите вашу программу под valgrind . Найдите и исправьте все ошибки, о которых он сообщает.

...