Newsgroup: it.comp.lang.c
Titolo: allocazione di stringhe

Salve a tutti
Come potrebbe farsi l'allocazione esatta (nessun byte sprecato in piu') di
stringhe attraverso le funzioni di allocazione dinamica - con stringhe
acquisite da input e di cui non si conosce a priori la loro lunghezza.

 ha scritto nel messaggio
news:9hi89l$r2d$1...@nreadB.inwind.it...


antony,
antony wrote:

   Dipende da cosa si intende per "a priori". Una possibilita` e` quella 
di leggere ogni stringa in un /buffer/ di dimensione presumibilmente 
adeguata alla lettura della stringa piu` lunga e, volta per volta, 
allocare la memoria richiesta dalla stringa.
--
Alla prossima,
Marco

 ha scritto nel messaggio
news:3B3CA431...@bar.va...


buffer di caratteri.
Tipo questa:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MEM_ERR  -2
#define IO_ERR   -1
#define MAXSTR  1024
#define NULL_BYTE '\0'
int my_fgets (FILE * stream, char **s);
char *stralloc (const char *s);
int
main (void)
{
  char *test = NULL;
  if (!my_fgets (stdin, &test))
    printf ("%s", test);
  return 0;
}
char *
stralloc (const char *s)
{
/* Data una stringa costante ne determina la lunghezza
ed alloca lo spazio in maniera dinamica */
  size_t size;
  char *temp;
  size = strlen (s) + 1;
  temp = (char *) malloc (sizeof (char) * size);
  if (temp)
    {
      temp[size - 1] = NULL_BYTE;
      strncpy (temp, s, size - 1);
      return temp;
    }
  return NULL;
}
int
my_fgets (FILE * stream, char **s)
{
  char buff[MAXSTR];		/* spero che 1024 carattri siano abbastanza */
  char *pointer;		/* rimuovo il \n */
  if (fgets (buff, sizeof (buff), stream))
   {
      pointer = strrchr (buff, '\n');
      if (*pointer)
	*pointer = NULL_BYTE;
      if (!(*s = stralloc (buff)))
	{
	  /* errore in memoria */
	  return MEM_ERR;
	}
      return 0;
    }
  return IO_ERR;
}
-- 
"I've a wonderful proof for this theorem,
but the border of this page is too small
for writing it here" - Pierre Fermat
--




 ogni volta lo spazio necessario al nuovo carattere letto?
realloc ad ogni singolo nuovo carattere ????????
che pessima idea !
Alex

singolo carattere e poi copiarlo con strcpy(punt_stringa,buffer);
Toglimi una curiosita', lo fai solo per testare le funzioni di
allocazione o stai ancora usando un VIC 20 ?
ciao, acc.   
a...@libero.it


wrote:

Guarda che quello proposto da Marco e' il sistema piu' indicato! 
Allocare un carattere per volta e' una pessima idea.
Se il problema e' quello di risparmiare memoria, perche' non ti
orienti sulla compressione delle stringhe.
ciao, acc.   
a...@libero.it

come nella seguente: ma non funziona completamente
Te credo...uhm forse cercavi qualcosa come questo (vedi sotto)?
Vi prego di perdonarmi gli eventuali errori, che sicuramente ci sono.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MEM_ERR  -2
#define IO_ERR   -1
#define NULL_BYTE '\0'
#define CARR     '\n'
#define MAXSTR 10
int my_fgets2 (FILE * stream, char **s);
char *xsrealloc (char *ptr, size_t size);
int
main (void)
{
  char *test = NULL;
  my_fgets2 (stdin, &test);
  printf ("%s", test);
  free (test);
  return 0;
}
char *
xsrealloc (char *ptr, size_t size)
{
  size_t strsz;
  strsz = strlen (ptr) + (size * sizeof (char)) + 1;
  ptr = realloc (ptr, strsz);
  if (!ptr)
    return NULL;
  ptr[strsz - 1] = NULL_BYTE;
  return ptr;
}
int
my_fgets2 (FILE * stream, char **s)
{
  char t;
  char *buffer;
  int i, j;
  buffer = malloc ((MAXSTR + 1) * sizeof (char));
  buffer[MAXSTR] = NULL_BYTE;
  i = 0;
  j = MAXSTR;
  while ((t = getc (stdin)) != CARR)
    {
      buffer[i] = t;
      i++;
      if (i > j)
	{
	  buffer = xsrealloc (buffer, MAXSTR);
	  j = j + MAXSTR;
	}
    }
  *s = buffer;
  return 0;
}
-- 


per testare le funzioni di allocazione e poi perche' mi hanno detto che un
vero programmatore non dovrebbe sprecare piu' memoria di quanta ne sia
necessaria, anche se oggi vi sono quantitativi enormi di ram: Sara' vero!!!!
"acc" <a...@libero.ita> ha scritto nel messaggio
news:7qqpjt8s3pm080iib...@4ax.com...


necessaria, anche se oggi vi sono quantitativi enormi di ram: Sara' vero!!!!
Si, verissimo. Cmq io ti ho fornito una seconda soluzione che penso 
sia addatta al tuo problema. Vedi il mio post precedente.
Leggere un carattere per volta, e per ogni carattere fare una realloc,
non e` una cosa accettabile. Leggere MAX caratteri e metterli 
in un buffer, e` accettabile. Nel mio esempio le dimensioni del buffer
erano limitate. Un consiglio: vedo che fai troppo affidamento sulle
strcpy e sulle strcat ma cosa succede se per esempio codifichi nel 
seguente modo ?:
int main(int argc, char **argv)
{
char buff[20];
strcpy(buff,argv[1]);
return 0;
}   
-- 
On Newton's epitaph:
"Sibi gratulentur mortales tale tantumque
existisse humani generis decus" 
--

 necessaria, anche se oggi vi sono quantitativi enormi di ram: Sara' vero!!!!
In parte si ma non è così semplice. In ogni situazione vi sono forze che
spingono in direzioni spesso incompatibili. E' compito del programmatore
trovare il miglior punto di equilibrio tra queste forze.
Ad esempio, può accadere che la velocità di un algoritmo sia
direttamente proporzionale alla memoria da esso utilizzata. In questo
caso appare chiaro che la semplicistica tecnica "spreco meno memoria
possibile" può risultare inaccettabile.
EMG

la stringa potrebbe essere anche un testo lungo una intera pagina .
se riallochi ad ogni carattere ottieni delle prestazioni pessime; se
proprio non vuoi allocare neanche un byte in piů potresti prima
salvare tutti i caratteri in una lista e poi copiarli in un array; cmq
anche in questo caso prestazioni paurose: perché vuoi fare una cosa
del genere?
Anto
--
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

 necessaria, anche se oggi vi sono quantitativi enormi di ram: Sara'
vero!!!!
Si e' vero, ma nel limite del razionale ;-)
Scommetto che sei uno di quelli che esegue la funzione swap di due variabili
int seza l'uso della variabile tmp, ma con l'uso degli XOR bit a bit ?!?
(per risparmiare una variabile)...
/* versione "normale" */
void Swap1(int *a, int *b)
{
    int tmp;
    tmp=*a;
    *a=*b;
    *b=tmp;
}
/* versione XOR */
void Swap2(int *a, int *b)
{
    *a ^= *b;
    *b ^= *a;
    *a ^= *b;
}
Ci ho preso ?!? ;-)
Scherzi a parte, quelle dici e' vero (ma non e' sempre una regola), mi piace
molto la risposta di EMG:
<QUOTE EMG>
Ad esempio, può accadere che la velocità di un algoritmo sia
direttamente proporzionale alla memoria da esso utilizzata. In questo
caso appare chiaro che la semplicistica tecnica "spreco meno memoria
possibile" può risultare inaccettabile.
</QUOTE>
Nel tuo caso (anche se non e' quello descritto da EMG, o meglio non
propriamente) io non mi porrei tutti questi problemi...
Alex

 mi piace molto la risposta di EMG:
Grazie!
EMG

 ha scritto nel messaggio
news:rcA8O2oaw5bWlp...@4ax.com...


 .. si... io non tanto!!!
Ma chi e' questo ?... e' tutto il messaggio che dici l'esperto etc...
Alex

 tesina ;-)
possa essere avvalorata da qualcosa di tangibile.
  .
Edoardo
"Alex" <nom...@bow.wow> ha scritto nel messaggio
news:E4t%6.9346$F85.3...@news.infostrada.it...


 nessuno ti ha obbligato a rispondermi ...
Proprio per questo avresti dovuto ringraziarmi, mondo ingrato ;-)
Ti ho fatto l'esempio delle 1000 allocazioni, del buffer, di perche' e' un
vantaggio, di perche' non si spreca memoria come dicevi tu, etc...
mah........
Il bello e' che ti lamenti della mia "offesa" nel dubitare della parola
"tesi", ma non mi hai detto nulla a riguardo. Visto che ti sei offeso e ti
sei sfogato su di me, dimmi : E' una tesi del 5 anno di informatica od
ing.informatica ??? Io, mi spiace, e' piu' forte di me, ma credo proprio non
sia possibile ! (ora piu' di prima, visto che per dimostrarmelo hai bisogno
di ricorrere a tutto questo casino! Cosa te ne frega di cosa io pensi ?!?
Tanto piu' che non ci conosciamo.)
Alex
P.S. ragazzi scusate se sono stato prolisso, ma, credo mi possiate capire,
mi sembrava di sognare !!! (era cosi' offensivo il mio msg ?!?)

 Sara' vero!!!!
Ovviamente  bisogna valure  caso  per caso. Cmq,  allocare  un byte  per
volta  ed  usare  realloc  per   ogni  byte  aggiuntivo  puo`  rivelarsi
*molto*  inefficente a  causa  dell'overhead delle  continue chiamate  a
malloc/realloc.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
"La Via prosegue senza fine."
	Bilbo Baggins - Il Signore degli Anelli - J.R.R. Tolkien

</QUOTE>
che, tra l'altro, è di vitale importanza in molte situazioni. Ci sono
algoritmi che risolti per via esaustiva possono richiedere complessità
del tipo O(2^n) o O(n!), mentre se si usa un algoritmo di
programmazione dinamica diventano lineari: e la programmazione
dinamica si basa proprio (grosso modo) sul presupposto di salvare
tutti i risultati parziali per evitare di ricalcolarseli (quindi usa
più memoria).


mi sembrava di sognare !!! (era cosi' offensivo il mio msg ?!?)
per quel che mi riguarda sono d'accordo con te, mi sembrava un
messaggio normalissimo.
