Указатель на локальную переменную в C++
Возможный дубликат:
Можно ли получить доступ к памяти локальной переменной вне ее области?
У меня есть следующий код в C++
int* foo()
{
int myVar = 4;
int* ptr = &myVar;
return ptr;
}
int main()
{
printf("val= %d", *foo());
return 0;
}
Вывод, который я получаю:
val = 4
Так что мой вопрос так как myVar - локальная переменная, не должна ли она исчезнуть после возврата из функции? и не должен ли указатель на него быть нулевым указателем?
4 ответа
Так что мой вопрос так как myVar - локальная переменная, должна ли она исчезнуть после возврата функции?
Да. Это указывало бы на адрес, который вы установили. Тем не менее, регион был локальным для этой функции. Предположим, что он не принадлежит вам после того, что он указывает, выходит за рамки.
Это так же неправильно, как:
uint8_t* p = (uint8_t*)malloc(count);
free(p);
p[0] = 1;
но гораздо сложнее диагностировать ошибку для ваших инструментов, поскольку в стеке будет существовать область (если ее не оптимизировать).
и не должен ли указатель на него быть нулевым указателем?
Нет. C и C++ не справляются с этим за вас.
В твоем случае, 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;
}
Адрес в 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;
}
Память, содержащая адрес, который содержал int myvar, и любые другие локальные переменные, принадлежащие этой функции, не выделяется в момент возврата функции, однако в C нет процедуры очистки, поэтому значение в памяти останется неизменным в течение этого небольшого момента между возвратом и printf доступ к нему.
Нераспределение (или освобождение, то же самое) памяти в C похоже на удаление файла в Windows, где содержимое файла пока еще находится на диске, но будет перезаписано всякий раз, когда эта область снова понадобится для чего-то другого. Вы по-прежнему можете читать содержимое, но вы не должны доверять тому, что читаете.