Jump to content

Memória em C


Localhost
 Share

Recommended Posts

  • Replies 75
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

O Baderous tem razão, mas vou tentar dar uma explicação rápida e concisa, e não cometer muitos erros. Não sou especialista em arquitectura de computadores, e por aqui haverá sempre quem possa corrigir-me e discutir o que eu disser 😁

A memória está "separada" em 3 "tipos": estática, dinâmica e automática. Notem-se as aspas, porque a distinção é feita unicamente pelo gestor de memória, não havendo mais nenhuma diferença entre os "tipos".

Na memória estática são armazenadas as variáveis globais e as variáveis estáticas. As variáveis aqui armazenadas têm sempre como valor inicial "tudo a zeros", assegurado pelo gestor de memória no início da aplicação, a menos que sejam inicializadas com outro valor.

A memória dinâmica é onde as funções malloc e afins vão buscar a memória quando são invocadas. É onde reside o heap.

A memória automática é onde reside o stack, e consequentemente onde são alojadas as variáveis locais.

Desaparecido.

Link to comment
Share on other sites

Eu dividiria ainda mais a memória:

- Rodata: constantes read-only

- Code/Text Segment: código (instruções). Também é read-only

- Data: variáveis globais não inicializadas a 0. Tem uma parte read-only e outra read-write.

- BSS: variáveis globais e static que são inicializadas a 0 (pelo programador ou não)

- Heap: conteúdo das alocações dinâmicas de memória

- Stack: variáveis locais

Agora há N situações em que se poderia ver em que zona da memória vai ficar guardada determinada variável e em que zona fica o seu conteúdo.

Parece-me a mim que estás a querer entrar no domínio da stack frame, isso já é demasiado low-level para estas horas. x)

Link to comment
Share on other sites

Era mesmo isso, stack frame, eu tive a ver aqui algumas cenas. É o seguinte xD: Eu tive a dar aqui uma revisão nos ponteiros porque não tinha percebido muito bem e agora que até percebo como funciona e isso tudo envolvi-me em mais e mais coisas xD. Isto tudo levou-me ao estado comum do: "oh não, eu não sei nada de nada" ahahahah, e queria sair deste estado de ignorância  😁

Btw & off-topic: Vocês sabem em que faculdades se dá C em programação? Eu estava a pensar na FEUP, o que me dizem? É que estou no 10º ano e as dúvidas são grandes (:

P.S. É só um pequeno off-topic

here since 2009

Link to comment
Share on other sites

Há muitas situações a considerar, muitas vezes ocorrem erros como o tentar alterar algo que é read-only, e só nos apercebemos disso após pesquisarmos um bocado acerca do assunto e, eventualmente, aterramos num fórum qualquer onde alguém já teve a mesma dúvida e aprende-se com a explicação da mesma. Mas uma coisa é certa, dá muito jeito ter noção da "arrumação da casa" num programa.

Dá-se C em todas as faculdades.

Link to comment
Share on other sites

Mas uma coisa é certa, dá muito jeito ter noção da "arrumação da casa" num programa.
. Exacto por isso mesmo é que eu vim aqui perguntar. Eu gosto de saber como as coisas funcionam e isto está a dar comigo em doido  😁

EDIT: Quanto ao off-topic, não tinha o conhecimento disso, pensava que cada faculdade dava diferentes linguagens :s

here since 2009

Link to comment
Share on other sites

Olá pessoal. Hoje com aquilo das conversas da memória e isso tudo lembrei-me de trabalhar ainda mais os ponteiros. Resolvi fazer um programa e obtive um resultado muito interenssante e tirei uma conclusão dele, no entanto não sei se está correcta. O code:

#include <stdio.h>

int fun(int *num2)
{
   printf("In fun function: %d\nAddress: %p\n", *num2,num2);
   sqr(num2);
   return(0);
}

int chama(int *numero, int(*func)(int *num))
{
   printf("In chama funtion: %d\nAddress: %p\n", *numero,numero);
   func(numero);
   return(0);
}

int sqr(int *num)
{
   int (*p2)(int *num4);
   printf("In sqr function: %d\nAddress: %p\n", *num,num);
   p2 = fun;
   chama(num,p2);
   return(0);
}

void main(void)
{
   int (*p)(int *num2);
   int nmr = 10;
   int *number;
   printf("In main function: %d\n", nmr);
   p = sqr;
   number = &nmr;
   chama(number,p);
}

Se compilarem e executarem vão ver que ao fim de algum tempo dá um segmentation fault. O quê que eu fiz? Mudei a variável nmr para o heap (ahahahah) e vi que já não dava o erro! Então conclui que a variável nmr é destruída no final de algum tempo. Será assim?

here since 2009

Link to comment
Share on other sites

O segmentation fault acontece por stack overflow. Acontece quando entras numa função recursiva, e nunca retornas: eventualmente o espaço no stack fica preenchido.

As variáveis locais só são "destruídas" quando o bloco que as contém termina. No caso, só quando a função main termina é que a variável nmr é libertada.

Não vejo em que é que criares dinamicamente o espaço para o inteiro influencia o erro. Aqui continua a acontecer. Mostra o código modificado, sff.

Desaparecido.

Link to comment
Share on other sites

LOL, que vergonha  ? Eu confundi, pensei que o heap era onde residiam as variaveis globais. O que eu queria dizer era que declarei nmr como o variável global!

Hoje tive 2horas a perceber isto de ponteiros para funções e fiquei com uma dúvida... Qual é a utilidade disto sem ser quando existe um stack overflow conseguir-mos mudar o EIP (isto já falando noutra coisa que tive a ver, atençao! Apenas por motivos de aprendizagem e para perceber melhor como trabalha a memória)!

here since 2009

Link to comment
Share on other sites

Mesmo declarando como variável global, não resolve. Sempre que fazes uma chamada a uma função, estás a ocupar um pouco do stack, para guardares, entre outras coisas, as variáveis locais e o endereço de onde foi chamada a função, para que quando a função termina, possas lá voltar. Quando a função retorna, esse espaço no stack é libertado. Se chamas uma função recursiva repetidamente, ela nunca vai terminar, e eventualmente todo o espaço do stack é utilizado. Nesse momento, ocorre um stack overflow.

Uma possível utilização de apontadores para função, e a 1ª que me vem à memória, é por exemplo em funções de ordenação de listas, em que passas à função de ordenação um apontador para uma função que compara dois elementos do tipo da lista que queres ordenar. Por exemplo, se queres ordenar de forma ascendente, passas como parâmetro uma função que diz se o 1º valor é superior ao 2º; se queres ordenar de forma descendente, passas uma função que diz se o 1º valor é inferior ao 2º.

Desaparecido.

Link to comment
Share on other sites

Mas a mim resolveu... Eu declarei como variável global, deixei a fazer o loop infinito durante algum tempo e não se deu o stack overflow.

Só uma coisa, denomina-se como stack overflow quando existe um "transboradamento" de dados ou quando se explora esse "transboradamento" de dados ao mudar o EIP da função ou seja o endereço do próximo comando da função?

EDIT: Atenção que a minha ideia naquele programa que mostrei não era fazer um loop infinto mas sim fazer um conjunto tão grande que me confundi-se o cerebro de maneira a eu ter de pensar sobre aquilo e finalmente perceber o que era aquilo!  😁

here since 2009

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.