2013-07-11 3 views
0

Привет, может кто-нибудь сказать мне, что переменная останется в памяти или будет немедленно уничтожена.Память и область действия переменной в c

#include <stdio.h> 

int main() 
{ 
    { 
     int a=1; 
     lab: 
     printf("Value of a : %d",a); 
    } 

    return 0; 
} 

будет оставаться в памяти или нет?

+0

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

+2

О, и *** 'int' ***' main() '... –

+0

@Mr Carbonic Acid; + Google_plex. Сколько раз мы видим void main()! – Bathsheba

ответ

3

Nope, a имеет локальный объем (обозначается между скобками), поэтому в закрывающей скобке он будет очищен.

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

Это имеет дополнительное преимущество в том, что компилятор инициализирует его для вас.

Вы можете попробовать следующее:

#include <stdio.h> 
int a; 

int main() 
{ 
    static int b; 

    int c; 

    printf("%d, %d, %d\n", a, b, c); /* a and b should print 0, printing c is undefined behaviour, anything could be there */ 

    return 0; 
} 

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

+2

Хороший ответ; будет +1, если вы упомянете, что использование статического файла испортит многопоточность. – Bathsheba

+0

@Bathsheba будет, спасибо! :) – Nobilis

+0

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

3

a разрушен (выталкивается из стека), когда вы переходите к следующему строке с printf, так что нет, он не останется в памяти на вашей строке комментариев.

+0

Я точно знал, что это специфично для реализации в C - то есть: хотя вы больше не можете получить к нему доступ по имени, он все равно может занимать место в стеке. – cHao

+0

Это может быть в памяти, так как было бы идеально для реализации просто перемещать курсор стека. Вероятно, вы обнаружите, что экземпляр другого int сразу после того, как скобка восстановит исходное значение. Однако полагаю, что это требует неприятностей. Вероятно, UB. – Bathsheba

1

Прежде всего: это не конкретная реализация. Стандарт Си явно говорит, что уход блока уничтожает объект с автоматическим (локальной объявлена) продолжительностью жизни:

Для такого объекта, который не имеет типа переменного длиной массива, его срок службы простирается от входа в блок с которым он связан , до тех пор, пока выполнение этого блока не закончится каким-либо образом. [ISO/IEC9899:TC3, 6.2.4, 5]

Конечно, это трудно проверить, потому что она теряет его сферу, тоже, в этом случае. (Другой способ легко проверить). Но это важно по официальной причине: если у вас есть указатель на этот объект, который живет дольше, чем объект, программа всегда некорректна и поведение не определено - даже реализация пусть объект жив. (Неопределенное поведение включает в себя то, что все работает нормально.)

+0

Концепция C «жизни» не так вырезана и высушена, как все это. «Время жизни объекта - это часть выполнения программы, в течение которой хранилище * гарантировано *, зарезервировано для него». (6.2.4, 1; выделение мое). Конец срока действия объекта не означает, что пространство очищается немедленно; это просто означает, что он больше не гарантируется стандартом для существования и только для этого объекта. (Реализация может иметь свои собственные правила и гарантии в любом случае, или это может быть не так.) – cHao

+0

Ваша цитата из ISO/IEC9899: TC3? Я не могу найти это, но: «У объекта есть время хранения, определяющее его время жизни. Существуют три периода хранения: статические, автоматические и распределенные. Выделенное хранилище описано в 7.20.3». в 6.2.4, 1. Но это не имеет значения: на что вы ссылаетесь, заключается в том, что реализация, которая удерживает объект, больше соответствует стандарту. Это важно для * разработчика компилятора *. Для * приложения-разработчика * срок службы заканчивается в точке, в которой остался блок. Даже реализация сохраняет объект дольше, поскольку * программа-программист * умер. ... –

+0

... Каждая программа на C, которая полагается (использует) в большей степени, является неправильной программой C, даже если реализация обещает удерживать объект дольше и даже эта реализация будет соответствовать стандарту. Степень не обозначена как реализация. –

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