Duvida : C malloc

Started by Alienaqtor, 24 de June , 2008, 03:03:34 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Alienaqtor

Alguem poderia explicar a diferenca entre :

printf("Entre com o nº total de alunos: ");
scanf("%d", &numero);
notas = (int *) malloc(numero * sizeof(int));

e

printf("Nome 1: ");
nome2 = (char *) malloc(10 * sizeof(char));
scanf("%s",nome2);

as variaveis "nome2" e "notas" sao ponteiros.

char *nome2;
int *notas;

a parte que tem o malloc eu nao entendi a logica, o que significa ? porque aquele 10 esta ali? o que o malloc esta fazendo.  se alguem puder me explicar agradeceria porque o texto que estou lendo nao deixou muito claro o que significava todos os comandos que estao ali.


programas completos ::



void main()
{
int *notas;
int numero;
int i;

printf("Entre com o nº total de alunos: ");
scanf("%d", &numero);
notas = (int *) malloc(numero * sizeof(int));

for(i=0; iprintf("Digite a nota do aluno %d ",i+1);
scanf("%d",notas[ i ]);
printf("\nA nota do aluno %d é %d:", i+1, notas[ i ]);
}

}


--------------------


void main(void)
{
char nome1[10];
char *nome2;
printf("Nome 1: ");
scanf("%s", nome1);

printf("Nome 2: ");
nome2 = (char *) malloc(10 * sizeof(char));
scanf("%s", nome2);

printf("Nome 1: %si\n", nome1);
printf("Nome 2: %s", nome2);
}

shake

O Malloc realiza a alocação dinâmica de memória, por exemplo o seguinte caso:
nome2 = (char *) malloc(10 * sizeof(char));
Você deseja alocar um espaço de memória para a variável "nome2" do tipo "ponteiro char" com 10 vezes o tamanho de um char (1 byte), ou seja, vc está alocando uma variável do mesmo tamanho da outra já declarada "nome1[10]".

Já a linha:
notas = (int *) malloc(numero * sizeof(int));
Faz o mesmo que o descrito em cima porém com inteiros.

Deu pra entender???

Alienaqtor

Agora consegui entender  mas a variavel "nome2" nao fica do mesmo tamanho da "nome1" ela se torna expansivel e vai aumentar seu tamanho conforme eu coloque dados nela, estou certo?

ainda nao entendi direito o que realmente a variavel "numero" e o 10 fazem.

vou dar mais uma estuda aqui, vlw ai shake.

#phobia

Quote from: "Alienaqtor"Agora consegui entender  mas a variavel "nome2" nao fica do mesmo tamanho da "nome1" ela se torna expansivel e vai aumentar seu tamanho conforme eu coloque dados nela, estou certo?

Creio que não!
Ela fica do mesmo tamanho porque você declarou "nome1[10]", então, como disse o shake, você deseja alocar um espaço de memória para a variável "nome2" do tipo "ponteiro char" com 10 vezes o tamanho de um char, logo, 10 = 10. xD

Quote from: "Alienaqtor"ainda nao entendi direito o que realmente a variavel "numero" e o 10 fazem.

- A variável "numero" vai armazenar o número total de alunos que o usuário digitar.

- Quanto ao 10.. 10 vezes o tamanho de um char.


Bom, corrijam-me por favor se estiver errado, pois tem muito tempo que vi isso (C)!
Espero ter ajudado...

Flws!

Alienaqtor

phobia , mas se ela (nome2) nao eh expansivel e eh igual a variavel "nome1" nao sei o que esta dando errado , olhe :
   


         Este eh o codigo fonto do programa.
#include <stdio.h>
#include <malloc.h>
int main()
{
char nome1[10];
char *nome2;
printf("Nome 1: ");
scanf("%s", nome1);

printf("Nome 2: ");
nome2 = (char *) malloc(10 * sizeof(char));
scanf("%s", nome2);

printf("Nome 1: %s\n", nome1);
printf("Nome 2: %s\n", nome2);
}


     Ele le as duas variaveis porem , depois de mostra-las aparece um erro e isso so aconte quando a variavel "nome1" armazena mais do que 10 caracteres,  na variavel "nome2" ja coloquei mais de 30 e nao apareceu erro nenhum , se elas sao iguais porque esta acontecendo isso?   

   

felipe@FelipeRs-desktop:~$ ./testei
Nome 1: forumsecuritydarkers     [b]Aqui pede para entrar com as 
                                                           variaveis[/b]
Nome 2: forumsecuritydarkers


Nome 1: forumsecuritydarkers    [b]e aqui eh a saida[/b]
Nome 2: forumsecuritydarkers


*** stack smashing detected ***: ./testei terminated
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)[0xb7ec1138]
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x0)[0xb7ec10f0]
./testei[0x80484d4]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7dea450]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:01 482521     /home/felipe/testei
08049000-0804a000 rw-p 00000000 08:01 482521     /home/felipe/testei
0804a000-0806b000 rw-p 0804a000 00:00 0          [heap]
b7dd3000-b7dd4000 rw-p b7dd3000 00:00 0
b7dd4000-b7f1d000 r-xp 00000000 08:01 996858     /lib/tls/i686/cmov/libc-2.7.so
b7f1d000-b7f1e000 r--p 00149000 08:01 996858     /lib/tls/i686/cmov/libc-2.7.so
b7f1e000-b7f20000 rw-p 0014a000 08:01 996858     /lib/tls/i686/cmov/libc-2.7.so
b7f20000-b7f23000 rw-p b7f20000 00:00 0
b7f24000-b7f2e000 r-xp 00000000 08:01 979264     /lib/libgcc_s.so.1
b7f2e000-b7f2f000 rw-p 0000a000 08:01 979264     /lib/libgcc_s.so.1
b7f2f000-b7f33000 rw-p b7f2f000 00:00 0
b7f33000-b7f34000 r-xp b7f33000 00:00 0          [vdso]
b7f34000-b7f4e000 r-xp 00000000 08:01 979219     /lib/ld-2.7.so
b7f4e000-b7f50000 rw-p 00019000 08:01 979219     /lib/ld-2.7.so
bfc16000-bfc2b000 rw-p bffeb000 00:00 0          [stack]
Cancelado



o que estou fazendo errado ?

#phobia

Pelo que eu entendi que o Shake disse, é expansivel sim cara, mas só até 10.
Ficando assim igual a "nome1" ao atingir o limite (10).

Eu entendi isso.


Qual o erro?
Aqui funcionou blz!

Alienaqtor

Quote from: "#phobia"Pelo que eu entendi que o Shake disse, é expansivel sim cara, mas só até 10.
Ficando assim igual a "nome1" ao atingir o limite (10).

Eu entendi isso.


Qual o erro?
Aqui funcionou blz!


O erro eh esse , so acontece quando a variavel "nome1" armazena mais do que 10 caracteres , mas esse error eh comum , ou deveria ser , creio eu , porque a variavel pode armazenar so 10 caracteres  , o que eu nao entendi eh como a variavel "nome2" que , como vc disse , deveria ser igual a  "nome1" pode armazenar mais do que 10, isso significa q ela eh expansivel ? 

segue o error abaixo ::

felipe@FelipeRs-desktop:~$ ./testei
Nome 1: forumsecuritydarkers     [b]Aqui pede para entrar com as
                                                           variaveis[/b]
Nome 2: forumsecuritydarkers


Nome 1: forumsecuritydarkers    [b]e aqui eh a saida[/b]
Nome 2: forumsecuritydarkers


*** stack smashing detected ***: ./testei terminated
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)[0xb7ec1138]
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x0)[0xb7ec10f0]
./testei[0x80484d4]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7dea450]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:01 482521     /home/felipe/testei
08049000-0804a000 rw-p 00000000 08:01 482521     /home/felipe/testei
0804a000-0806b000 rw-p 0804a000 00:00 0          [heap]
b7dd3000-b7dd4000 rw-p b7dd3000 00:00 0
b7dd4000-b7f1d000 r-xp 00000000 08:01 996858     /lib/tls/i686/cmov/libc-2.7.so
b7f1d000-b7f1e000 r--p 00149000 08:01 996858     /lib/tls/i686/cmov/libc-2.7.so
b7f1e000-b7f20000 rw-p 0014a000 08:01 996858     /lib/tls/i686/cmov/libc-2.7.so
b7f20000-b7f23000 rw-p b7f20000 00:00 0
b7f24000-b7f2e000 r-xp 00000000 08:01 979264     /lib/libgcc_s.so.1
b7f2e000-b7f2f000 rw-p 0000a000 08:01 979264     /lib/libgcc_s.so.1
b7f2f000-b7f33000 rw-p b7f2f000 00:00 0
b7f33000-b7f34000 r-xp b7f33000 00:00 0          [vdso]
b7f34000-b7f4e000 r-xp 00000000 08:01 979219     /lib/ld-2.7.so
b7f4e000-b7f50000 rw-p 00019000 08:01 979219     /lib/ld-2.7.so
bfc16000-bfc2b000 rw-p bffeb000 00:00 0          [stack]
Cancelado


ps : compilei no linux , vc disse q deu certo , vc compilou pelo windows ? tentou colocar mais de 10 caracteres no primeiro nome?


vou tentar entender aqui ,

vlw phobia e shake


flw

#phobia

Sim, velho.
Compilei no Win XP SP3 usando DevC++.

Testei por exemplo 12 caracteres no "nome1" e 10 no "nome2".
Funcionou blz!

Agora... se exagerar nao vai.. rsrs
Você tem que fazer o teste ai pra ver... acho que ai ficará até mais fácil de entender...

Até eu já tô ficano confuso com isso.. hsuahusaa

Dexa o Shake chegar que ele tem mais a manha!


Flw velhim!
abs.

shake

Cara é o seguinte,

testei o programa aqui e talz...
o nome1 recebe mais de 10 caracteres...
recebe sim, porém rode esse programa passo a passo e coloque marcadores nas variáveis nome1 e nome2 pra vc ver o resultado.

Vc verá que var nome1 armazena somente os 10 primeiros caracteres digitados e a var nome2 por ser um ponteiro para char ele vai conter um endereço de memória que contenha os caracteres digitados!

Sendo mais objetivo

nome1 irá armazenar somente os 10 primeiros caracteres.

nome2 irá armazenar o endereço de memória (até 10 caracteres) do que será escrito para apontar na hora de imprimir na tela!

Agora deu pra entender legal???
Qlq coisa pergunta ai!

Flwz

Alienaqtor

Compilando esse programa no windows com o DevC++ tanto a variavel nome1 quanto a nome2 receberam  mais do que 10 caracteres e ambas mostraram a string completa (com mais de 10 caracteres) ou um caracter apenas ( ex "%c", nome1[18]; ) tentei adicionar os marcadores para ver o que acontecia mas nao sei usar direito o debug,  nao sei o que deveria ter acontecido , se era para mostrar mais do que 10 caracteres ou nao  mas foi o que aconteceu , mas de qualquer forma, valeu pelo ajuda ai shake e phobia , ja achei outro exercicio aqui e estou tentando resolve -lo (bem mais dificil por sinal ) se tiver mais alguma duvida (com certeza terei  =)  ) volto a postar , vlw ,  Flws 

nibbles

Bom, é o seguinte.
quando você cria um ponteiro, ele aponta para um local 'X' na memória (você não sabe onde e nem o que tem lá)
malloc vai buscar um local de memória sequencial livre (que nem o SO nem nenhum programa esteja usando) e reservar para aquele ponteiro (e apontá-lo para o início desta sequencia)
só.
imagine como um vetor, é igual, porém dinâmico.

o fato de 'não dar erro' é porque, após o final desta sequência os outros endereços estavam livres também, apesar de não estarem sendo usados, eles PODEM vir a ser usados (não estão reservados), ou seja, tudo que você gravou após o '10' pode ser perdido. e quando atingir um local onde a memória está reservada para outro ponteiro, você terá um erro.

ou seja, use o que alocar ou o comportamento será indefinido.



"A diversão do inteligente é se fingir de burro para aquele que se finge de inteligente."
"ENGENHARIA SOCIAL. Porque não existe patch para a ignorância humana."

Alienaqtor

Quote from: "nibbles"Bom, é o seguinte.
quando você cria um ponteiro, ele aponta para um local 'X' na memória (você não sabe onde e nem o que tem lá)
malloc vai buscar um local de memória sequencial livre (que nem o SO nem nenhum programa esteja usando) e reservar para aquele ponteiro (e apontá-lo para o início desta sequencia)
só.
imagine como um vetor, é igual, porém dinâmico.

o fato de 'não dar erro' é porque, após o final desta sequência os outros endereços estavam livres também, apesar de não estarem sendo usados, eles PODEM vir a ser usados (não estão reservados), ou seja, tudo que você gravou após o '10' pode ser perdido. e quando atingir um local onde a memória está reservada para outro ponteiro, você terá um erro.

ou seja, use o que alocar ou o comportamento será indefinido.


=) , Agora tudo faz sentido !!! vlw pela explicacao nibbles, agora posso seguir meus estudos tranquilo.