2014-10-06 6 views
0

У меня возникли проблемы возвращения недействительным указатель на другую функцию в С.Возвращение Пустоты Указатель обрезает значение

Заголовочный файл:

void *function2(void); 

main.C

#include "myHeader.h" 

void function1(){ 
    void *temp = NULL; 
    temp = function2(); 
} 

FUNCTION2.C

int a = 3; 

void *function2(void){ 
    printf("Memory Address %p\n",&a); 
    return (void *) &a; // value of &a is 0x100023444 
} 

Howev er, значение temp в функции 1() равно 0x3444, а не 0x100023444.

Кто-нибудь знает решение для этого или если я что-то делаю неправильно?

EDITED: Похоже, что заголовок был добавлен не в том месте, что привело к проблеме, описанной AndreyT и Jonathan ниже, что, по-видимому, устранило проблему усечения. Спасибо за помощь ребята!

+1

'return & a' (адрес локальной переменной) является неопределенным поведением. –

+0

извините, исправлено, что – peterrandon

+0

@YuHao: Я не думаю, что возвращение адреса локальной переменной является неопределенным поведением - это ...? – Mehrdad

ответ

3

Учитывая изменение вопроса, я уверен, проблема заключается в том, что вы не объявили function2(), прежде чем использовать его. Следовательно, компилятор считает, что он возвращает int, а не void *. Он также должен жаловаться на фактическое определение, не соответствующее принятому объявлению.

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

Обратите внимание, что вы должны объявить void *function2(void); потому опуская void в списке параметров означает что-то совсем другое - это означает, что компилятор ничего о том, что параметры он принимает, не то, что она не принимает никаких параметров не сказал. (Это отличие от C++.)

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

extern void *function2(void); 

void function1(void) 
{ 
    void *temp = function2(); 
    printf("Address: %p\n", temp); 
} 

void *function2(void) 
{ 
    int a = 3; 
    printf("Address: %p\n", &a); 
    return &a; // value of &a is 0x12000
} 

Или определить function2() перед определением function1().


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

0

Этот ответ отличается от усечения.

В функции2() a есть локальная переменная. Здесь область действия и время жизни a ограничены функцией2. Поэтому возврат адреса к другой функции является незаконным. Это приведет к неопределенному поведению. Пожалуйста, обратите больше внимания на изучение класса хранения в C

5

Внутри function1 вы вызываете еще незаявленную функцию function2. В классическом языке C (C89/90) это разрешено, но предполагается, что необъявленная функция возвращает int. По-видимому, на вашей платформе указатели имеют ширину 64 бит, а int - 32 бит. Это то, что вызывает усечение вашего 64-битного значения указателя 0x12000 до 32 бит, давая вам 0x1234.

Формально ваш код имеет неопределенное поведение, так как после того, как компилятор предположил, что function2 возвращает int, вы объявили его возвратом void *. Даже компиляторы C89/90 обычно вызывают предупреждение об этой проблеме (и компилятор C99 сообщает об ошибке). Вы проигнорировали это?

Либо переместить все определение function2 и поместите его над function1

void *function2(void) { 
    int a = 3; 
    return &a; 
} 

void function1 (void){ 
    void *temp = NULL; 
    temp = function2(); 
} 

Или, наоборот, объявить function2 перед вызовом

void *function2(void); 

void function1(void) { 
    void *temp = NULL; 
    temp = function2(); 
} 

void *function2(void) { 
    int a = 3; 
    return &a; 
} 

Вы должны объявить свои функции, прежде чем называть их (предпочтительно с прототипом).

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