2015-11-04 5 views
-2

мне нужно объявить переменную, которая не в памяти стека, но в куче, как показано нижеГлобальная декларация находится в стеке или куче?

struct mystruct *name; 

Должен ли я объявить его вне всех функций (даже за пределами основной()) на начало файла?

+1

em? переменная на куче? hmmmm –

+1

C не указывает детали реализации. – Olaf

+0

@SouravGhosh: вы можете использовать подход, основанный на куче, вместо стека. – Olaf

ответ

1

Обратите внимание, что переменная никогда не объявлена ​​«на куче». Только память, на которую указывает указатель, может быть выделена на (из) кучи.

В вашем примере вы можете объявить name действительно вне любой функции, а затем он будет существовать в глобальной памяти. Вы также можете обрабатывать переменную внутри функции, которой предшествует ключевое слово static. Этот последний будет выделять переменную также в глобальной памяти, но она будет видна только в функции, где вы ее объявили.

Чтобы использовать переменную указателя, теперь вы должны выделить память для ее указания, которую вы выделяете в куче, используя malloc.

0

TL; DR версия

Вы не можете объявить переменную таким образом, что сама переменная живет в куче.

Джеймс Michener Версия определение языка

: C не говорит о штабеле или куче; он говорит о продолжительности хранения.

Объекты с auto продолжительности хранения (ничего заявленного в блоке и без static ключевого слова) имеют время жизни, которые простираются от начала этого блока и в конце, когда блок выходит :

void foo(void) 
{ 
    int a = 0;      // lifetime of a extends to the end of 
            // the function 
    for (int i = 0; i < 10; i++) // lifetime of i and b extend to the end 
    {         // of the for loop 
    int b = a + i;  
    printf("b = %d\n", b);  
    } 
} 

Большинство реализаций выделить хранилище для auto объектов из аппаратного стека, поскольку стек делает это поведение простым в использовании .

Объекты с static продолжительности хранения (что-либо объявленные вне функции или с static ключевого слова) имеют сроки службы, которые простираются от времени программа загружается в память, пока программа не выйдет:

int a = 0;     // lifetime of a extends over the lifetime of 
          // the entire program 
int main(void) 
{ 
    static int b = 10;   // lifetime of b also extends over the lifetime 
          // of the program, but is only visible within 
          // main 
    ... 
} 

Большинство реализаций зарезервировать для хранения static объектов внутри самого исполняемого файла (для исполняемого файла, использующего формат ELF, такие объекты будут сохранены в разделах , .data или .rodata).

Объекты с allocated продолжительности хранения (что-нибудь выделяется malloc, calloc или realloc) имеют сроки службы, которые простираются от времени, когда они выделяются, пока они не будут явно высвобождены с вызовом free.

int *foo(size_t size) 
{ 
    int *ptr = malloc(sizeof *ptr * size); 
    return ptr;        
} 

void bar(void) 
{ 
    int *p = foo(10);      
    // do something with p 
    free(p); 
} 

В переменныеptr и p существуют только для времен жизни их соответствующих функций, и они будут, как правило, выделяется из стека. Объект как переменные указывает на существует с момента выделения malloc, пока он не будет освобожден с free.

Большинство реализаций выделяют хранилище для allocated объектов из кучи.

У вас нет прав для Объявление объект с allocated срок хранения; единственный способ создать такой объект - через malloc, calloc, или realloc. Независимо от того, какой объект, который вы объявляете для хранения значения указателя, возвращаемого любой из этих функций, будет иметь продолжительность хранения auto или static.


1. На практике, для хранения всех локальных объектов выделяются при входе функции и выпущен на выходе функции, независимо от того, является ли время жизни объекта находится над целой функцией или ограничивается блоком внутри функции. Однако вы никогда не должны полагаться на доступность этого хранилища за пределами жизни этого объекта. Например, времена жизни i и b ограничены петлей for; даже если хранилище для каждого из них может быть выделено при вводе функции, вы не должны пытаться получить доступ к этому хранилищу вне тела цикла.

2. C был разработан на машине со стеком, в конце концов.