2012-04-06 3 views
1

Можно создать дубликат:
Can a local variable's memory be accessed outside its scope?Указатель на локальную переменную в C++

Я следующий код в C++

int* foo() 
{ 
    int myVar = 4; 
    int* ptr = &myVar; 
    return ptr; 
} 

int main() 
{ 
    printf("val= %d", *foo()); 
    return 0; 
} 

Выход я получаю:

val = 4 

Итак, мой вопрос в том, что myVar - это локальная переменная, не следует ли ее уйти после возвращения функции? и не должен ли указатель на него быть нулевым указателем?

ответ

3

Так что мой вопрос в том, что myVar - это локальная переменная, если она не исчезнет после возвращения функции?

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

Это же неправильно, как:

uint8_t* p = (uint8_t*)malloc(count); 
free(p); 
p[0] = 1; 

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

И не должен ли указатель на него быть нулевым указателем?

№ C и C++ не справляются с этим для вас.

0

Адрес в ptr * останется выделенным, и если вы снова вызовете функцию, это изменит указатель. По крайней мере, это была бы моя теория. C++ не перезаписывает ваш указатель по причинам производительности.

int foo(int val) { 
    int myVar = val; 
    int* ptr = &myVar; 
    return ptr; 
} 

int main() 
{ 
    int *ptr = foo(4); 
    foo(3); 
    printf("val= %d", *ptr); //will print 3 
    return 0; 
} 
+0

Хах! теперь, когда вы снова вызываете функцию. Я просто немного экспериментировал, и появился еще один вопрос!: D Так что я только что немного изменил свой код 'code int main() { printf (" * bar =% d \ n ", foo()); printf ("* bar2 =% d \ n", foo()); система («пауза»); return 0; } ' бар и бар2 имеют такое же значение! : O – 0x56794E

+0

Правильно, каждой объявленной переменной присваивается одна постоянная ячейка памяти. Это место не изменится во время выполнения программы. Но, как упомянул пользователь966379, он не гарантированно станет уникальным местом для всех областей. –

0

память, содержащая адрес, состоявшейся INT MyVar и любые другие локальные переменная, принадлежащие к этой функции нераспределенные тому моменту, когда функция возвращает, однако не существует процедура очистки в C, так что значение в памяти будет оставайтесь неизменными в течение этого небольшого момента между обратным и printf доступом к нему.

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

2

В вашем случае printf("val= %d", *foo()) печатает значение мусора. Поскольку другого кода нет, эти данные не были изменены.

Вы запустите этот код, вы получите идею

int* foo() 
    { 
     int myVar = 4; 
     int* ptr = &myVar; 
     return ptr; 
    } 

    int* foo1() 
    { 
     int myVar = 5; 
     int* ptr = &myVar; 
     return ptr; 
    } 
    int main() 
    { 
     int* x = foo(); 
     int* x1 = foo1(); 
     printf("val= %d", *x); 
     return 0; 
    } 
Смежные вопросы