2015-12-11 3 views
0

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

Так из приведенной ниже программы я ожидал какой-то предупреждения

#include<stdio.h> 
int *fun() 
{ 
    int i=10; 
    return &i; 
} 

int main(void) 
{ 
    int *p=fun(); 
    return 0; 
} 

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

Но если сохранить значение переменной я в некотором целом указателем, а затем возвращает значение от удовольствия, как этот

#include<stdio.h> 
int *fun() 
{ 
    int i=10,*p; 
    p=&i; 
    return p; 
} 

int main(void) 
{ 
    int *p=fun(); 
    return 0; 
} 

Почему я не получаю какой-либо вес подрабатывать?

+1

где вы указали 'p' во второй функции кода' fun() '. Я думаю, вы имели в виду 'int i = 10, * p;' – Haris

+0

Пожалуйста, исправьте вторую программу, как в том, что такое p, и где она объявлена. Кроме того, вы имеете в виду, что вы получаете предупреждение в первой программе, а не во втором? – thepace

+0

Извините за Типо. Я отредактировал вопрос. Да, я получаю предупреждение сначала, но не во второй программе –

ответ

2
  • Компилятор предупреждает только тогда, когда вы возвращаете адрес локальной переменной напрямую.
  • Это не предупреждение, если вы вернете указатель адреса.
  • Он не проверяет, присвоен ли указатель адреса локальной переменной.

Дубликата: Return address of local variable in C

Почему обе программы будет reult неопределенного поведения: https://www.fayewilliams.com/2015/06/30/a-challenge-discussion-returning-pointers-to-local-variables/

0

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

Вот как компилятор смотрит на вещи, он может только смотреть на синтаксис, делая статически рассчитанное предупреждение.

также, только что нашел это: Return address of local variable in C

0

Вы будет получить предупреждение:

warning: function returns address of local variable [-Wreturn-local-addr]

но вы сусло скомпилировать с помощью командной строки opt ион -Wall. Я бы также рекомендовал использовать -Werror. Используйте эти два варианта всегда. Вы были предупреждала :-)

Кроме того, обратите внимание, что значение на самом деле не уничтожен [как в Java]. Он все еще существует в возвращенной ячейке памяти, которая является частью фрейма стека для fun. Он останется неповрежденным для краткого (то есть непредсказуемого/неопределенного) количества времени.

Это просто, если вы вызываете какую-либо другую функцию, кадр стека этой функции будет иметь тот же адрес, и все, что он делает, [вероятно] сделает значение fun i похоже на мусор.

Например:

fun stack frame: 
    int i;   // offset 0x00 
    int *p;   // offset 0x04 

fn2 stack frame: 
    double q;  // offset 0x00 
    int x;   // offset 0x08 
    int j;   // offset 0x0C 

Итак, после того, как вы звоните fun, вы звоните fn2 и устанавливает q в 123,7. После возвращения из fn2 первые четыре байта q перезаписали пространство, занимаемое fun's i. Следовательно, значение «мусора» для i

0

Это потому, что в C только потому, что переменная выходит за пределы области действия, это не означает, что система освобождает эту память, как в java. В C, если вы создаете переменную и устанавливаете указатель на эту переменную, то до тех пор, пока у вас есть указатель на эту переменную, вы можете получить значение и изменить. вот что вам нужно сделать, чтобы распечатать значение, которое имеет p.

#include<stdio.h> 
int *fun() 
{ 
    int num=2;//this sets some memory address equal to 2 
    int *p=&num; //this sets some memory address equal to 
       //the memory address of num 
    return p; //this returns a "pointer" to the value 
       //of num 
} 

int main(void) 
{ 
    int *p=fun(); 
    printf("num equals: %d\n",*p); //need star to get to the value of num 
         //if you tried to print p by itself it would work 
         //but it would be a memory address which 
         //means nothing to the program 
    return 0; 
} //output is "num equals: 2" 
Смежные вопросы