Jump to content

Parque estacinamento, limitar arreys


costricardo
 Share

Recommended Posts

Sim. Se queres criar arrays dinamicamente (em tempo de execução) tens de pedir ao utilizador quantos lugares quer e crias um array com esse número de lugares, utilizando alocação dinâmica. Podes também definir um máximo, no entanto, vai estar a gastar recursos desnecessários e o utilizador pode até ultrapassar esse limite que defines.

By the way, bom "texto pessoal".

here since 2009

Link to comment
Share on other sites

Sim. Não te esqueças é de chamar a função free para destruir esse bloco que alocaste.

Na minha opinião a maneira mais simples de se entender alocação dinâmica é tentando resolver este problema: Criar uma função que peça o nome do utilizador do programa e que depois retorne essa string para a função main, sem utilizar variáveis globais, ou seja, o nome nessa função de input vai ser armazenado numa string local dessa função.

Para resolver isto tens de ter um bom conhecimento sobre ponteiros, visto que alocação dinâmica baseia-se em ponteiros.

here since 2009

Link to comment
Share on other sites

Para resolveres o teu problema tens de ter conhecimentos em alocação dinâmica. Na minha opinião a melhor maneira de aprenderes alocação dinâmica é perceberes e resolveres, por ti, o problema que apresentei, com mais ou menos ajudas. Logo, o problema que te apresentei é mais para perceberes alocação dinâmica e não para resolveres o teu problema especificamente.

Já agora, publicitando um pouco, vai ao meu blog que tem um lá um artigo, ainda em desenvolvimento, sobre ponteiros. Prometo continuar a 2ª parte um dia destes. Enquanto isso, procura na net e em livros sobre o mesmo assunto.

Se precisares de uma "mãozinha" para resolver o problema que apresentei diz. 

here since 2009

Link to comment
Share on other sites

Já agora, para os mais experientes, alguém me poderia dizer por que razão é que este código está a dar os resultados "correctos", além de me dar um warning na compilação...?

Código:

#include <stdio.h>

char * input ()
{
    char name[120];

    printf (">>> ");
    scanf ("%s", name);
    printf ("Nome: %s\n", name);
    printf ("Endereço: %p\n\n", name);

    return name;
}

int main (void)
{
    char *my_name;

    my_name = input ();
    printf ("Nome: %s\n", my_name);
    printf ("Endereço: %p\n", my_name);

    return 0;
}

Warning:

test.c: In function ‘input’:

test.c:12: warning: function returns address of local variable

Penso que este warning era de esperar, no entanto, não esperava que me desse os resultados correctos.

here since 2009

Link to comment
Share on other sites

Dá certo porque é um programa pequeno, num maior é muito provável que não dê. O que aconteceu é que fizeste return de um endereço de memória que já não te pertence (porque a função termina e o endereço diz respeito a uma variável alocada na stack). O endereço é guardado na variável my_name (não é de estranhar que o endereço apareça correctamente no printf), mas depois vais imprimir algo que tanto pode ser como não ser aquilo que esperas (a string que escreveste). Chama-se a isso uma dangling reference e o seu comportamento é indefenido. Podes ler mais aqui:

http://stackoverflow.com/questions/1224042/c-returning-a-pointer-to-an-automatic-variable

http://www.eskimo.com/~scs/cclass/int/sx5.html

Link to comment
Share on other sites

Já agora, mais baixo nível:

O que acontece é que quando a função retorna, o CPU não apaga a memória, isso seria dispendioso. Limita-se a mudar o valor do Stack Pointer para o original antes da função ser chamada. O que significa que os dados continuarão lá até que sejam reescritos, normalmente quando posteriormente se criam novas variáveis locais ou se chamam outras funções.

Portanto, tiveste "sorte" porque a printf() não usou memória suficiente na stack para subscrever o valor da name.

❝The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.❞- John Carmack on software patents

A list  of command line apps

Link to comment
Share on other sites

@Baderous: eu já tinha entendido isso. Quando a função input que criei encontra o return é automaticamente destruído o seu stack frame. Daí ter achado estranho naquele endereço ainda existir a string que introduzi.

Obrigado pelos links, vou ler.

@IceBrain: isso que referiste acontece em todos os casos? O CPU nunca vai destruir aquele bloco para não desperdiçar recursos, ou isto só aconteceu por ser um "programa pequeno" como o Baderous referiu?

here since 2009

Link to comment
Share on other sites

Acontece sempre. Apagar memória é ineficiente e inútil na maioria dos casos.

A estrutura da stack é a seguinte:

http://img830.imageshack.us/img830/8770/programcallstack3.png

Cada chamada a uma função cria um Frame nova. Quando ela retorna, o Stack Pointer volta ao valor anterior. No exemplo da imagem, quando a função actual (que tem a Frame Activa) retorna, o Stack Pointer é mudado para 17, e ignoram-se os dados que lá ficam, passam a ser "lixo", pronto a ser reutilizado.

❝The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.❞- John Carmack on software patents

A list  of command line apps

Link to comment
Share on other sites

O endereço não é guardado. O que o compilador faz é calcular quantos bytes existem na frame activa no momento do return e gera a intrução "ret" seguida desse número de bytes. Por exemplos, se a frame tem 16 bytes naquele momento:

ret 16

Assim, o SP é subtraído em 16 antes da função retornar.

O return address que é guardado na stack serve para o Program Counter, para saber que instrução estava a ser executada, não para o SP.

❝The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.❞- John Carmack on software patents

A list  of command line apps

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.