2011-12-18 4 views
5

фрагменты кода из двух исходных файлов C:указатель изменения возвращаемого значения после вызова функции

Ac

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

Bc

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 безрезультатно.

+0

Что такое 'chnl' и где он определен? – Jan

+0

Его глобальная переменная, определенная в B.c - Channel chnl; и инициализируется в другом файле, chnl = malloc (sizeof (Channel *)); – Vasu

+0

Может случиться так, что при вызове динамической библиотеки инициализация не будет выполнена? –

ответ

5

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

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

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

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

+0

+1: листы почти всегда неправильны в C :) – pmg

+0

У меня есть прототип в файле заголовка, который включен как в Ac, так и в BcИ будет ли он работать для статических библиотек, если проблема связана с отсутствием прототипа? – Vasu

+0

BTW, когда я использую статическую библиотеку, адреса всегда находятся в 32-битном диапазоне. Нужен ли мне флаг компилятора при создании общей библиотеки? Я использую - gcc -fPIC -shared -Wl, -soname – Vasu

1

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

+0

он отлично работает в valgrind! thats vexing me too :( – Vasu

+1

Затем постарайтесь решить проблему до полного, но минимального примера, и у нас будет трещина. Не забудьте включить процесс сборки, который вы используете, что может быть виновником. –

Смежные вопросы