Comportamento estranho de malloc() [Resolvido]

Iniciado por mhkgalvez, 06 de Julho de 2010, 16:32

tópico anterior - próximo tópico

mhkgalvez

Olá pessoal, quero criar um algorítmo que defina o tamanho de um valor:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
 int *i = (int*) malloc (1);
 *i = 40000;
 printf("%d\n", *i);
 return 0;
}


Assim, eu esperava que este int ficasse de 1 byte, neste caso, o 40000 deveria ser rejeitado por ser grande. Mas isso não ocorre. O valor é atribuído corretamente. Pq?
"A quem vencer, eu o farei coluna no templo do meu Deus, e dele nunca sairá; e escreverei sobre ele o nome do meu Deus, e o nome da cidade do meu Deus, a nova Jerusalém, que desce do céu, do meu Deus, e também o meu novo nome."

rapaqueca

se apagares os * penso q fico bom o programa.
eu nao percebo muito de C, mas em C++ ao fazeres int *i estás a criar um ponteiro q aponta para um numero inteiro, qualquer q seja o tamanho dele.

Darcamo

Confesso que sua pergunta me deixou realmente intrigado.
Você não tem como dizer quantos bytes um inteiro vai ocupar, não importa a quantidade de memória que você alocou com o malloc.
Se você alocar mais memória do que o necessário será apenas um desperdício. No entanto, como você só alocou um byte então na minha opinião deveria dar segmentation fault quando você tenta armazenar o número.

De qualquer forma, mesmo que não tenha dado erro é melhor você usar o operador sizeof para determinar a quantidade de memória a ser alocada pelo malloc. C já te dá muitas possibilidades de "errar alguma coisa" e é melhor não procurar outras desnecessariamente.   :P

A leitura do link abaixo pode ser interessante
http://www.c-faq.com/

mhkgalvez

Citação de: rapaqueca online 09 de Julho de 2010, 06:50
se apagares os * penso q fico bom o programa.
eu nao percebo muito de C, mas em C++ ao fazeres int *i estás a criar um ponteiro q aponta para um numero inteiro, qualquer q seja o tamanho dele.

Não. Em C isso é necessário para alocar memória. Mas tirando o * fica na mesma.
"A quem vencer, eu o farei coluna no templo do meu Deus, e dele nunca sairá; e escreverei sobre ele o nome do meu Deus, e o nome da cidade do meu Deus, a nova Jerusalém, que desce do céu, do meu Deus, e também o meu novo nome."

HelderC

Dá um printf no sizeof(int) para saber realmente qual o tamanho de um tipo inteiro...

mhkgalvez

já tinha feito. Foram 4 bytes (64 bits)
"A quem vencer, eu o farei coluna no templo do meu Deus, e dele nunca sairá; e escreverei sobre ele o nome do meu Deus, e o nome da cidade do meu Deus, a nova Jerusalém, que desce do céu, do meu Deus, e também o meu novo nome."

fpissarra

#6
Citação de: Darcamo online 10 de Julho de 2010, 07:57
... No entanto, como você só alocou um byte então na minha opinião deveria dar segmentation fault quando você tenta armazenar o número.

Isso também me confundiu. Eu também esperava encontrar um Segmentation Fault neste código, mas fui dar uma olhada no manual da LIBC:

Citar... The block that malloc gives you is guaranteed to be aligned so that it can hold any type of data. In the GNU system, the address is always a multiple of eight on most systems, and a multiple of 16 on 64-bit systems.

Assim, suponho, por causa desse alinhamento, é possível que malloc(1) seja, na verdade, malloc( 8 ). De fato, se fizermos:

#include <malloc.h>
#include <stdio.h>

int main(int argc, char **argv)
{
 int *p = (int *)malloc(1);

 p[0] = 1; p[1] = 2;

 printf(%d %d\n", p[0], p[1]);

 free(p);

 return 0;
}


p[1] será impresso errado (pelo menos no meu teste), mas não ocorretá um SEGFAULT. Mas acrescentando um p[3], obtive um SEGFAULT no free(p).

Citação de: Darcamo online 10 de Julho de 2010, 07:57
De qualquer forma, mesmo que não tenha dado erro é melhor você usar o operador sizeof para determinar a quantidade de memória a ser alocada pelo malloc. C já te dá muitas possibilidades de "errar alguma coisa" e é melhor não procurar outras esnecessariamente. :P

Darcamo, como sempre, está mais que correto... Mesmo sabendo dessa característica da LIBC, não devemos explorá-la. É bem mais prudente alocar os blocos de memória com o tamanho correto.

mhkgalvez

Citação de: fpissarra online 16 de Julho de 2010, 15:58
Darcamo, como sempre, está mais que correto... Mesmo sabendo dessa característica da LIBC, não devemos explorá-la. É bem mais prudente alocar os blocos de memória com o tamanho correto.

Também concordo. Só fiz isso a título de testes mesmo. :D

Valeu pela ajuda. Só uma coisa a mais: onde se encontra esse manual da LIBC?
"A quem vencer, eu o farei coluna no templo do meu Deus, e dele nunca sairá; e escreverei sobre ele o nome do meu Deus, e o nome da cidade do meu Deus, a nova Jerusalém, que desce do céu, do meu Deus, e também o meu novo nome."

Darcamo

Eu até imaginei que o malloc poderia alocar um tamanho mínimo. O estranho é que testei com o valgrind e ele acusou que vazava apenas um byte. De qualquer forma, fica explicado pelo que está escrito no manual da libc.