Newsgroup: it.comp.lang.c
Titolo: problema con calloc

char *buf;
buf=(char*)calloc(512,sizeof(char));
printf("%d",sizeof(buf));
mi sto scervellando...dovrebbe allocare un buffer char di 512byte e invece
me ne alloca 4...stavo scrivendo un programma che doveva scrivere dei
blocchi in un file e non li faceva della dimensione corretta pensavo fosse
fwrite e invece è questo...
ci sarà un errore ma sicuramente non me ne son accorto....non vorrei che
fosse qualche problema di windows...ma questo non dovrebbe essere c
standard?

 fwrite e invece è questo...
La calloc ti sta allocando correttamente un buffer di 512 byte.
E' che sbagli ad usare sizeof....
sizeof(buf) ti dice la dimensione della variabile buf.
La variabile buf e' un puntatore a carattere e quindi come
variabile occupa giustamente 4 bytes.
ciao,
g.

ok...problema trovato grazie:P
"Giovanni Resta" <g.r...@iit.cnr.it.nospam> ha scritto nel messaggio
news:bv7sbr$gn9$1...@newsfeed.cineca.it...


 ha scritto nel messaggio
news:BBKRb.155839$VW.63...@news3.tin.it...

Occhio, la memoria allocata e' effettivamente 512 (a meno che buf ==NULL
dopo la calloc)!
E' che buf e' dichiarato come un puntatore e quindi il suo sizeof e' di 4
byte (come tutti i puntatori sulla tua macchina).
E' giusto quello che la printf stampa!
Se un array lo dichiari inizialmente come puntatore, poi non c'e' modo di
risalire allo spazio
allocato per quell'array.
Provare per credere:
-----------------------------------
#include <stdio.h>
int main(void) {
  char * buf1;
  char buf2[512];
  buf1 = (char *) calloc(512,sizeof(char));
  if (buf1 != NULL) {
    printf("buf1 => %d, buf2 => %d\n",sizeof(buf1),sizeof(buf2));
  }
  return 0;
}
-----------------------------------
Ciao,
Ema

 allocato per quell'array.
Un modo standard forse no, ma a seconda del compilatore
possono esistere dei metodi non standard. D'altra parte
il compilatore questo numero lo deve memorizzare da qualche
parte, per poterlo usare con la free e con la realloc.
Per esempio, usando il gcc sotto linux, mi sembra che
un numero che e' in relazione con la memoria allocata
(piu' o meno) venga memorizzato nei 4 bytes prima
del vettore.
Cioe', se faccio
char *c;
int *p;
c = malloc(512);
p = (int *)c;
printf("%d\n", *(p-1));
mi stampa un numero vicino a 512.
Questa comunque solo per curiosita', non e' certo
un metodo che consiglierei...
ciao,
g.

 un metodo che consiglierei...
Ma la allocazione/deallocazione dinamica dell memoria non e' demandata al (e
quindi poi gestita dal)  S.O.?
In realta' la sto sparando li', perche' bisognerebbe vedere come son fatte
le *alloc/free ma comunque mi immaginavo che
- quando allochi te chiedi memoria al SO e lui ti dice da dove iniziare a
scrivere
- quando liberi te gli dici dov'e' che stavi scrivendo e lui libera la
memoria relativa (ricordandosi quanta ne avevi allocata).
In effetti mi sembra strano che sia il compilatore a doversi occupare di
questo: in effetti a run-time oramai il compilatore ha ben poco da
lavorare...
Sei sicuro di quello che hai detto? Se hai 5 min. e se ti va di spiegarci
meglio la faccenda mi farebbe piacere.
Cmq grazie.
Ciao,
Ema

 meglio la faccenda mi farebbe piacere.
Putroppo non mi ricordo piu' un tubo. Quella della dimensione
memorizzata prima dell'array e' una cosa che ho letto almeno 10
anni fa. Non mi ricordo nemmeno se era riferita al linguaggio C....
Comunque il fatto che nella posizione -1 dell'array ci
sia un valore di poco superiore alla dimensione e'
vera (almeno con il gcc): per esempio
#include<stdio.h>
#include<stdlib.h>
int main()
{
   int i, *p;
   for (i=100; i<=1000; i+=100)
     {
       p=calloc(i,sizeof(int));
       printf("%d -> %d\n",i,p[-1]);
     }
    return 0;
}
a me stampa
100 -> 409
200 -> 809
300 -> 1209
400 -> 1609
500 -> 2009
600 -> 2409
700 -> 2809
800 -> 3209
900 -> 3609
1000 -> 4009
Se qualcuno sa come funziona la faccenda potrebbe spiegare anche a me...
ciao,
g.

 g.
Col codice che hai postato ottengo anche io lo stesso risultato!!!
Magia? Mistero? Apparizioni? Spaaaarizioni?
Boh.
Comunque ho proseguito le indagini e leggermente modificato il tuo prog:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
  int i;
  char * p;
  for (i=100; i<=1000; i+=100)
    {
      p=calloc(i,sizeof(char));
      printf("%d -> %d\n",i,*(p-2));
    }
  return 0;
}
ottenendo
100 -> 105
200 -> -47
300 -> 49
400 -> -103
500 -> -7
600 -> 97
700 -> -63
800 -> 41
900 -> -119
1000 -> -15
Prova un po'.
Questo non mi sembra molto chiaro. Il tuo giochino funziona solo con array
di interi?
Attendiamo qualche guru.
Ciao,
Ema

 di interi?
Direi di no, ma considerando che da me gli interi occupano 4 bytes,
devo scrivere cosi' (uso un altro puntatore *ip per chiarezza)
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
   int i, *ip;
   char * p;
   for (i=100; i<=1000; i+=100)
     {
       p=calloc(i,sizeof(char));
       ip = (int *) p;
       printf("%d -> %d\n",i,*(ip-1));
     }
   return 0;
}
100 -> 105
200 -> 209
300 -> 305
400 -> 409
500 -> 505
600 -> 609
700 -> 705
800 -> 809
900 -> 905
1000 -> 1009
ciao,
g.


Chiedo scusa, era -4 (anche da me gli interi sono di 4 byte):
       printf("%d -> %d\n",i,*(p-4));
Ho copiato la prova sbagliata, ma il risultato era cmq quello che ho
postato.
Adesso non ho tempo. Poi guardo con + attenzione.
Cmq, quest'utlima tua prova e' veramente allucinante,
prima +5 poi +9 poi +5 poi +9...
== :- |
Ciao,
Ema
PS. Guruuuuuuuuu, dove sieteeeeee?

>        printf("%d -> %d\n",i,*(p-4));
Andare indietro con la numerazione produce dei risultati
imprevedibili.
E' undefined behavior, quindi può implicare anche la formattazione del
disco.

 lavorare...
Il compilatore si', ma la libc lavora eccome e malloc & c. dovrebbero 
essere proprio nella libc.
Non prenderlo come oro colato, ma a grandi linee il quadro dovrebbe 
essere questo.
Ciao,
Stefano.

 essere proprio nella libc.
malloc() & C. non sono altro che "wrapper" costruiti sulle funzioni
del sistema operativo (vedi quelle per la gestione dello heap sotto
Win32).

 del vettore.
Visto che parliamo di linux potresti guardare malloc/malloc.c nei souces
delle glibc. L'allocatore e` un po' complesso ma ottimamente commentato.
Luca
-- 
Home: 
http://kronoz.cjb.net
Il dottore mi ha detto di smettere di fare cene intime per quattro.
A meno che non ci siamo altre tre persone.