Será que este tipo de memória obter alocado na pilha ou a pilha?
-
06-07-2019 - |
Pergunta
No contexto do C ++ (não que isso importe):
class Foo{
private:
int x[100];
public:
Foo();
}
O que eu aprendi me diz que, se você criar uma instância de Foo como assim:
Foo bar = new Foo();
Em seguida, a matriz x é alocado na pilha, mas se você criou uma instância de Foo como assim:
Foo bar;
Em seguida, ele é criado na pilha.
Não consigo encontrar recursos on-line para confirmar isso.
Solução
Dada uma ligeira modificação do seu exemplo:
class Foo{
private:
int x[100];
int *y;
public:
Foo()
{
y = new int[100];
}
~Foo()
{
delete[] y;
}
}
Exemplo 1:
Foo *bar = new Foo();
- x e y estão na pilha:
- sizeof (Foo *) é criada na pilha.
- sizeof (int) * 100 * 2 + sizeof (int *) representa na pilha
Exemplo 2:
Foo bar;
- x está na pilha, e y é na pilha
- sizeof (int) * 100 está na pilha (x) + sizeof (int *)
- sizeof (int) * 100 é na pilha (y)
tamanhos reais podem diferir ligeiramente devido ao alinhamento de classe / struct dependendo do seu compilador e plataforma.
Outras dicas
A rigor, de acordo com o padrão a necessidade objeto não existe em uma pilha ou heap. O padrão define 3 tipos de 'duração de armazenamento', mas não estado exatamente como o armazenamento deve ser implementado:
- duração de armazenamento estático
- duração de armazenamento automático
- duração de armazenamento dinâmico
duração de armazenamento automático é normalmente (quase sempre) implementado usando a pilha.
duração de armazenamento dinâmico é tipicamente implementado usando a pilha (em última instância, via malloc()
), embora este pode ser substituído até mesmo pelo usuário do compilador.
duração de armazenamento estático é o que normalmente conhecido como globals (ou armazenagem estática).
O padrão tem a dizer sobre essas coisas (A seguir, trechos formar vários bits de 3.7 - Armazenamento de duração):
estáticos e durações de armazenamento automático estão associados com objetos introduzidos por declarações (3.1) e implicitamente criado pela implementação (12.2). A duração de armazenamento é dinâmico associado com objetos criados com novo operador (5.3.4).
...
Todos os objetos que não têm dinâmica duração de armazenamento nem são locais têm duração de armazenamento estático. O armazenamento para estes objetos deve durar o duração do programa (3.6.2, 3.6.3).
...
autoLocal objetos declarado explicitamente ou registar-se ou não declarado explicitamente estática ou externa têm automática duração de armazenamento. O armazenamento para esses objetos dura até que o bloco em que são criados saídas.
...
Os objetos podem ser criados dinamicamente durante a execução do programa (1.9), utilizando novos-expressões (5.3.4), e destruiu usando de exclusão de expressões (5.3.5). Um C + + Implementação fornece acesso e manejo, armazenamento dinâmico via as funções globais de alocação operador de novo e novo operador [] e as funções globais desalocação operador de apagar e operador excluir [].
...
A biblioteca fornece padrão definições para a dotação global e funções desalocação. Alguns alocação global e deallocation funções são substituíveis (18.4.1)
E finalmente (em relação a matriz no seu exemplo de classe):
3.7.4 Duração da sub-objetos [basic.stc.inherit]
A duração de armazenamento de subobjects membro, subobjects classe de base e os elementos de matriz que é de sua completa objeto (1,8).
Um objecto do tipo Foo leva o tamanho de 100 ints armazenados em sequência. Se você criá-lo na pilha, você vai ter tudo na pilha. Se você fazê-lo com o novo, vai ser na pilha como parte do objeto.
Esta é parte da especificação da linguagem, eu não tenho certeza do que sua pergunta é.
Sim, o x
matriz de membro será criado na pilha se você criar o objeto Foo
na pilha. Quando você alocar memória dinâmica para Foo
você está pedindo para a memória de sizeof(Foo)
comprimento (mais possivelmente alguma sobrecarga de memória, mas vamos ignorar isso por enquanto), que em seu código de exemplo implica o tamanho de 100 int
s. Este tem para ser caso para o tempo de vida de objetos do tipo Foo
(e seus dados interna) para escopos cruzadas.
Se você não criar o objeto Foo
na pilha, e a matriz interna de Foo
não é um ponteiro para que você alocar memória com new
no construtor do Foo
então essa matriz interna será criado na pilha. Mais uma vez, este tem de ser o caso, para que a matriz seja automaticamente limpa, sem quaisquer delete
s quando termina o escopo. Especificamente,
struct Foo {
int* y;
Foo() : y(new int()) { }
~Foo() { delete y; }
};
criará y
na pilha, independentemente de um objeto Foo
foi criado na pilha ou na pilha.
Você quer dizer
Foo* bar = new Foo();
suponho. que é criado no heap.