2015-07-31 2 views
-3
int* intptr() 
{ 
    int i; 
    i=rand(); 
    printf("%d_____",i); 
    return(&i); 
} 

int main() 
{ 
    int* j,k,l; 
    j=intptr(); 
    k=intptr(); 
    l=intptr(); 
    printf("%d/n",j);printf("%d/n",k);printf("%d/n",l); 
} 

Здесь функция intptr возвращает указатель на первый вызов, и после этого все последующие вызовы возвращают Int 2752220Почему эта функция не возвращает указатель после первого вызова?

ответ

5

В другие ответы адрес неопределенное поведение, которое является бедным кодирования попрактиковаться образец кода экспонатов. Однако, как показано here, реальная проблема в том, что при определении

int* j,k,l; 

на Первая переменная j является указателем на int. Остальные являются регулярными целыми числами. Для того, чтобы сделать их все указатели, вы должны определить их как это:

int* j; 
int* k; 
int* l; 

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

+0

полностью проигнорировал его в ответ :( – Nishant

6

В коде int i; является локальным для функции intptr(). Вы не можете вернуть адрес i и использовать его в вызывающем. он вызывает undefined behaviour.

Чтобы уточнить, срок службы i закончился, когда функция intptr() вернулась. Адрес, который вы вернули (или попытался вернуться), стал недействительным. Использование возвращаемого значения, таким образом, UB.


После этого, пожалуйста, обратите внимание

  1. k и l имеют тип int, и вы пытаетесь для хранения int *. Неправильно. Результат определяется реализацией (см. §6.3.2.3, C11) и, скорее всего, это не то, что вы хотели в своем коде.
  2. j быть указателем, правильный способ печати по адресу указателя использовать

    printf("%p/n",(void *)j) 
    

    используя неверный тип аргумента (%d ожидает int, не int *) снова UB.

+0

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

+0

@NamanJain: Нет, вы вызываете UB. Технически оптимизирующий компилятор может обнаружить (и современные компиляторы фактически * будут определять *), что вы возвращаете адрес объекта, срок жизни которого уже закончился, когда результат этого возврата превращается в значение r. Компилятор имеет полное право производить ** что-либо ** в этой ситуации; он имеет полное право испускать программу, равную 'rm -rf /', и делает это только при выполнении. – datenwolf

+0

Как только функция 'inptr()' заканчивается, 'i' больше не существует. Адрес, указывающий на него, указывает на мусор. Мы не знаем, что находится в ячейке памяти, когда 'i' уничтожается в конце функции. – brandaemon

2

Вы пытаетесь вернуть что-то, что является локальным для функции intptr(), следовательно, независимо от вывода вы получаете даже для первого вызова, он не действует. Это неопределенное поведение. Потому что после того, как стек разматывания происходит (контроль возвращения из inptr() в main(), то i исчезает и любое значение по адресу его не удалось найти.

Вы можете сделать его статичным работать.

int* intptr() 
{ 
    static int i = 0; 
    i=rand(); 
    printf("%d_____",i); 
    return(&i); 

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