Crash..?

di il
55 risposte

55 Risposte - Pagina 3

  • Re: Crash..?

    AldoBaldo ha scritto:


    Potresti riscrivere la libreria standard del C...
    e che ci vuole? è a livello ragioniere programmatore.
    Hai mai pensato, ad esempio, a studiare come è implementata strlen()?
    
    
    
      1 /* Copyright (C) 1991, 1993, 1997, 2000, 2003 Free Software Foundation, Inc.
      2    This file is part of the GNU C Library.
      3    Written by Torbjorn Granlund (tege@sics.se),
      4    with help from Dan Sahlin (dan@sics.se);
      5    commentary by Jim Blandy (jimb@ai.mit.edu).
      6 
      7    The GNU C Library is free software; you can redistribute it and/or
      8    modify it under the terms of the GNU Lesser General Public
      9    License as published by the Free Software Foundation; either
     10    version 2.1 of the License, or (at your option) any later version.
     11 
     12    The GNU C Library is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15    Lesser General Public License for more details.
     16 
     17    You should have received a copy of the GNU Lesser General Public
     18    License along with the GNU C Library; if not, write to the Free
     19    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     20    02111-1307 USA.  */
     21 
     22 #include <string.h>
     23 #include <stdlib.h>
     24 
     25 #undef strlen
     26 
     27 /* Return the length of the null-terminated string STR.  Scan for
     28    the null terminator quickly by testing four bytes at a time.  */
     29 size_t
     30 strlen (str)
     31      const char *str;
     32 {
     33   const char *char_ptr;
     34   const unsigned long int *longword_ptr;
     35   unsigned long int longword, magic_bits, himagic, lomagic;
     36 
     37   /* Handle the first few characters by reading one character at a time.
     38      Do this until CHAR_PTR is aligned on a longword boundary.  */
     39   for (char_ptr = str; ((unsigned long int) char_ptr
     40             & (sizeof (longword) - 1)) != 0;
     41        ++char_ptr)
     42     if (*char_ptr == '\0')
     43       return char_ptr - str;
     44 
     45   /* All these elucidatory comments refer to 4-byte longwords,
     46      but the theory applies equally well to 8-byte longwords.  */
     47 
     48   longword_ptr = (unsigned long int *) char_ptr;
     49 
     50   /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
     51      the "holes."  Note that there is a hole just to the left of
     52      each byte, with an extra at the end:
     53 
     54      bits:  01111110 11111110 11111110 11111111
     55      bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
     56 
     57      The 1-bits make sure that carries propagate to the next 0-bit.
     58      The 0-bits provide holes for carries to fall into.  */
     59   magic_bits = 0x7efefeffL;
     60   himagic = 0x80808080L;
     61   lomagic = 0x01010101L;
     62   if (sizeof (longword) > 4)
     63     {
     64       /* 64-bit version of the magic.  */
     65       /* Do the shift in two steps to avoid a warning if long has 32 bits.  */
     66       magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL;
     67       himagic = ((himagic << 16) << 16) | himagic;
     68       lomagic = ((lomagic << 16) << 16) | lomagic;
     69     }
     70   if (sizeof (longword) > 8)
     71     abort ();
     72 
     73   /* Instead of the traditional loop which tests each character,
     74      we will test a longword at a time.  The tricky part is testing
     75      if *any of the four* bytes in the longword in question are zero.  */
     76   for (;;)
     77     {
     78       /* We tentatively exit the loop if adding MAGIC_BITS to
     79      LONGWORD fails to change any of the hole bits of LONGWORD.
     80 
     81      1) Is this safe?  Will it catch all the zero bytes?
     82      Suppose there is a byte with all zeros.  Any carry bits
     83      propagating from its left will fall into the hole at its
     84      least significant bit and stop.  Since there will be no
     85      carry from its most significant bit, the LSB of the
     86      byte to the left will be unchanged, and the zero will be
     87      detected.
     88 
     89      2) Is this worthwhile?  Will it ignore everything except
     90      zero bytes?  Suppose every byte of LONGWORD has a bit set
     91      somewhere.  There will be a carry into bit 8.  If bit 8
     92      is set, this will carry into bit 16.  If bit 8 is clear,
     93      one of bits 9-15 must be set, so there will be a carry
     94      into bit 16.  Similarly, there will be a carry into bit
     95      24.  If one of bits 24-30 is set, there will be a carry
     96      into bit 31, so all of the hole bits will be changed.
     97 
     98      The one misfire occurs when bits 24-30 are clear and bit
     99      31 is set; in this case, the hole at bit 31 is not
    100      changed.  If we had access to the processor carry flag,
    101      we could close this loophole by putting the fourth hole
    102      at bit 32!
    103 
    104      So it ignores everything except 128's, when they're aligned
    105      properly.  */
    106 
    107       longword = *longword_ptr++;
    108 
    109       if (
    110 #if 0
    111       /* Add MAGIC_BITS to LONGWORD.  */
    112       (((longword + magic_bits)
    113 
    114         /* Set those bits that were unchanged by the addition.  */
    115         ^ ~longword)
    116 
    117        /* Look at only the hole bits.  If any of the hole bits
    118           are unchanged, most likely one of the bytes was a
    119           zero.  */
    120        & ~magic_bits)
    121 #else
    122       ((longword - lomagic) & himagic)
    123 #endif
    124       != 0)
    125     {
    126       /* Which of the bytes was the zero?  If none of them were, it was
    127          a misfire; continue the search.  */
    128 
    129       const char *cp = (const char *) (longword_ptr - 1);
    130 
    131       if (cp[0] == 0)
    132         return cp - str;
    133       if (cp[1] == 0)
    134         return cp - str + 1;
    135       if (cp[2] == 0)
    136         return cp - str + 2;
    137       if (cp[3] == 0)
    138         return cp - str + 3;
    139       if (sizeof (longword) > 4)
    140         {
    141           if (cp[4] == 0)
    142         return cp - str + 4;
    143           if (cp[5] == 0)
    144         return cp - str + 5;
    145           if (cp[6] == 0)
    146         return cp - str + 6;
    147           if (cp[7] == 0)
    148         return cp - str + 7;
    149         }
    150     }
    151     }
    152 }
    
    Come puoi vedere anche quello che sembra semplice, in realtà, non lo è.
  • Re: Crash..?

    Da quel poco che ci ho capito, direi che lo scopo è velocizzare l'esecuzione cercando il terminatore non char per char ma procedendo per gruppi di char dimensionati in relazione alle caratteristiche del tipo unsigned long.

    Visto che l'implementazione sembra tratta dallo stesso compilatore che uso abitualmente, ho provato a scrivere un programmino che metta a confronto le prestazioni di strlen() con quelle di una ipotetica mialen() "banale" che confronta carattere per carattere:
    size_t mialen( const char *str ) {
        const char *p;
        for( p=str; *p; ++p );
        return p-str;
    }
    Quello che mi aspettavo, in un sistema a 32 bit, era grossomodo una prestazione tripla/quadrupla per strlen() rispetto a mialen(). Con un metodo spannometrico, usando clock() per rilevare i tempi e tre stringhe rispettivamente lunghe 33, 257 e 1027 caratteri, ho riscontrato queste prestazioni approssimate:
    Quantita' ripetizioni per passata: 1048575
    
    | Passata #1 | Passata #2 | Passata #3 | Passata #4 | Passata #5
    | 1/2.52     | 1/2.77     | 1/2.71     | 1/3.03     | 1/2.77
    | 1/3.85     | 1/3.50     | 1/3.55     | 1/3.50     | 1/3.18
    | 1/3.84     | 1/3.99     | 1/3.82     | 1/4.06     | 1/3.77
    
    | Passata #6 | Passata #7 | Passata #8 | Passata #9 | Passata #10
    | 1/2.77     | 1/2.00     | 1/2.00     | 1/2.00     | 1/2.77
    | 1/3.80     | 1/3.50     | 1/3.55     | 1/3.33     | 1/3.50
    | 1/3.78     | 1/3.82     | 1/3.85     | 1/3.97     | 1/3.82
    Da quel che appare, strlen() si avvicina in effetti a prestazioni quasi quadruple rispetto a mialen() all'allungarsi della stringa da verificare, mentre la differenza si riduce quando la stringa è più corta.

    Il tipo di ragionamento sui bit da confrontare, al momento, mi sfugge (in particolare il ruolo del "numero magico"). Richiede, evidentemente, di soffermarsi con "un po'" (con l'apostrofo) più lavorìo neuronale.
  • Re: Crash..?

    Mi rintroduco con il mio programma funziona al 90%( mi mancano sempre due soldi per fare una lira.)
    struct car{
    char marca;
    char modello[20];
    int vendute[20];
    int *punt;
    int dim;
    };
    
    main(){
    struct car a;
    int i;
    printf("quante auto vuoi inserire?:");
    scanf("%d",&a.dim);
    a.punt=malloc(a.dim*sizeof(int));
    printf("\ninserire marca,modello,quante vendute\n");
    for (i=0;i<a.dim;i++){
    scanf("%s %s %d",&a.marca,&a.modello,&a.vendute);}
    printf("dati inseriti in precedenza");
    for (i=0;i<a.dim;i++){
        printf("\n%s %s %d\n",a.marca,a.modello,a.vendute);}
    free(a.punt);
    }
    
    perchè sulla stampa crasha ?
  • Re: Crash..?

    È ancora tutto sbagliato. Ti ho detto che ci vogliono gli array di strutture e non hai fatto nulla. Adesso poi al posto di stringhe per marca e modello usi semplici char, quel puntatore non si sa a cosa serve; la dim nella struttura ... un disastro
  • Re: Crash..?

    Ma scusa se devo allocare il tutto dinamicamente cosa creo a fare un 'array?
    non riesco a creare una struttura come dici tu
    non riesco proprio a capire come creare una struttura e poi allocarla dinamicamente


    P.S sai dove posso trovare un buon libro/sito dove possa studiare questi array di struttura?
  • Re: Crash..?

    Parti cercando con google kernigan ritchie pdf
  • Re: Crash..?

    Toni, la struttura l'avevi già creata, quella con i campi marca, modello e unità vendute.

    Creare un array di strutture significa semplicemente avere un tot di strutture "in fila" in un blocco di memoria. Quel blocco di memoria può essere allocato in modo "silente" (automatico), col classico nome_struttura[quantita_elementi], oppure in modo "esplicito" (dinamico) con malloc, calloc, realloc... In entrambi i casi rimane quel che si diceva: un tot di strutture "in fila" in un blocco di memoria. Se allochi quel blocco dinamicamente, devi poi ricordarti di deallocarlo con free() quando non ti serve più e comunque prima di lasciare il programma.

    Dunque, se hai la tua struttura...
    struct Car {
        char marca[20];
        char modello[20];
        int vendute;
    };
    ...puoi allocarne un array dinamicamente con...
    Car *aCar; // aCar: puntatore a un Car o a un array di Car
    unsigned int qCar = 10; // qCar; quantita' di Car in aCar
    aCar = calloc( qCar, sizeof(*aCar) );
        /* sizeof() e' un operatore che ricava le dimensioni del tipo del suo **
        ** argomento; in questo caso, dice a calloc() quanto spazio occupa in **
        ** memoria un elemento di tipo struct Car; come conseguenza di questa **
        ** chiamata, calloc() alloca un unico blocco di memoria costituito da **
        ** qCar*sizeof(*aCar) byte e ne comunica l'indirizzo, che viene imma- **
        ** gazzinato nel puntatore aCar per poterlo successivamente usare     */
    
        /* da qui in avanti, hai dunque a disposizione un puntatore a uno spazio  **
        ** di memoria che puo' contenere qCar strutture di tipo Car che puoi usare**
        ** secondo le tue necessita'                                              */
        
    // fai quel che devi fare
        
        /* quando non ti serve piu' l'array di struct Car devi deallocarlo per non**
        ** "sprecare" memoria (memory leak); per deallocare lo spazio di memoria  **
        ** associato a un certo puntatore si usa free()                           **
        
    if( NULL != aCar ) { free( aCar ); aCar = NULL; }
    
        /* pare sia buona pratica controllare che il puntatore non sia NULL prima **
        ** di usarlo per una deallocazione, cosi' come impostarlo su NULL quando  **
        ** lo spazio di memoria al quale puntava e' stato deallocato, per evitare **
        ** di usarlo impropriamente, magari per "distrazione"                     **
    Ora, e mi riferisco a chi ne sa più di me, se ho scritto delle boiate (sempre possibile), fatemi la cortesia di non essere inutilmente acidi e di correggere le inesattezze spiegando cosa c'è che non va, possibilmente in modo "accessibile", se no direi che è inutile partecipare a un forum.
  • Re: Crash..?

    AldoBaldo ha scritto:


    Ora, e mi riferisco a chi ne sa più di me, se ho scritto delle boiate (sempre possibile)
    Toglierei il "possibile"
    fatemi la cortesia di non essere inutilmente acidi e di correggere le inesattezze spiegando cosa c'è che non va, possibilmente in modo "accessibile", se no direi che è inutile partecipare a un forum.
    Dipende dalle rispettive opinioni.
    In entrambi i casi rimane quel che si diceva: un tot di strutture "in fila" in un blocco di memoria.
    Questo è, in generale, falso
    Se allochi quel blocco dinamicamente, devi poi ricordarti di deallocarlo con free() quando non ti serve più e comunque prima di lasciare il programma.
    Sarei curioso che qualcuno, che ne sa meno di me, mi spiegassa PERCHE'.
    Una delle principali differenze tra dilettante e professionista (o anche tra "spugna fideistica" e "mediamente intelligente") è chiedersi PERCHE' si fa qualcosa.
    Se c'è un modo migliore, o peggiore, per farlo.
    Ma se non si sa PERCHE' fare qualcosa, qualsiasi approfondimento si interrompe necessariamente.
    /* pare sia buona pratica controllare che il puntatore non sia NULL prima **...
    Qui si aprirebbe il pippone su come funziona malloc (e cugini vari).
    Anzi malloc al PLURALE.

    La versione breve è sostituire "PARE" con "E'"
  • Re: Crash..?

    Grazie agli approfonditi e costruttivi chiarimenti della tua ultima risposta ho aggiunto un mare di conoscenze al mio arido deserto cognitivo, imparando tante, tante cose. Nel giro di un'altra decina di risposte così potrò ambire a qualche laurea honoris causa.
  • Re: Crash..?

    AldoBaldo ha scritto:


    Grazie ai chiarii costruttivi della tua ultima risposta ho aggiunto un mare di conoscenze al mio arido deserto cognitivo, imparando tante, tante cose. Nel giro di un'altra decina di risposte così potrò ambire a qualche laurea honoris causa.
    Certo che devi imparare tante cose, ma se ti aspetti che te le insegni io potresti doverlo fare a lungo.
    Comincia per ordine, da quella più facile.

    Affermi perentoriamente che le aree di memoria
    (a) DEVONO essere rilasciate, e
    (b) DEVI farlo prima di uscire dal programma.

    Spiega, o cerca e studia, PERCHE' (a) e PERCHE' (b).
    Magari scoprirai che (b) è (per tutti i sistemi operativi desktop, diciamo post Windows 98) inutile.
    E (a) - quasi sempre - lo è altrettanto.
    Tranne nel caso in cui... ti lascio per esercizio la risposta

    ---
    Per un livello leggermente migliore di conoscenza dovresti sapere cos'è la memoria (cosa per nulla scontata).
    Cos'è un processo (cosa per nulla scontata).
    Come interagiscono processi e memoria.
    E poi si potrà discutere di cosa (e come) fa malloc a fare la "magia" (anzi, meglio, LE malloc)

    Per la laurea honoris causa la strada è lunga.
  • Re: Crash..?

    Vedi, almeno io PROVO a interagire. Il tuo scopo pare invece essere AFFONDARE gli interlocutori o, quanto meno, la conversazione. Riporto qualche tua parola:
    [...] chiedersi PERCHE' si fa qualcosa. Se c'è un modo migliore, o peggiore, per farlo. Ma se non si sa PERCHE' fare qualcosa, qualsiasi approfondimento si interrompe necessariamente.
    Vale anche per le relazioni, sia pure virtuali e con sconosciuti.

    Circa le questioni che poni, per alcune credo di avere delle risposte forse plausibili, per altre MI PIACEREBBE avere delle delucidazioni ma hai dichiarato apertamente che non intendi darne, e va bene non sei certo obbligato, ma questo riporta alla questione del PERCHE' frequenti un forum se non vuoi interagire. Epperò, visto che rispondi, significa che desideri interagire, ma lo fai in modo costantemente caustico, al che uno si chiede perché -- senti la necessità di affermare te stesso? ti senti insicuro? intendi allontanare quelli che non sono alla tua altezza? un pizzico di sadismo? cos'altro? esplicita, così ch'io mi sappia regolare.

    Va be'.
  • Re: Crash..?

    Preso da dubbi costruttivi, chiedo al moderatore: c'è qualcosa di sbagliato nel MIO modo di intervenire quando cerco di rispondere a chi pone quesiti sui quali, con le migliori intenzioni, cerco di dare una mano a chi posso, quando posso, come posso? Se sì, me lo si faccia sapere, così che anche in questo caso io mi possa regolare. Per me non è una necessità vitale frequentare questo spazio -- lo faccio volentieri, ma se provoco scompiglio o anche solo fastidio, basta parlare e mi dileguo. Non prima di salutare, possibilmente con cordialità.
  • Re: Crash..?

    A parte tutto, Aldo, secondo me tu non hai chiaro che un forum non è un sostituto di libri, corsi o docenti.
    Non è detto che ti si debbano dare delle risposte CON tutte le spiegazioni del caso. Fossi in te ci rifletterei nel dire che 'altrimenti è inutile partecipare ad un forum'.

    Per capirci, se la soluzione del problema è l'array di strutture, si suggerisce e basta. Il forum è di tipo tecnico, non siamo badanti. Per le basi ci sono i libri, l'allocazione in memoria se contigua o no e perché qui è OT, non si chiacchera liberamente e indiscriminatamente di tutto, soprattutto se sono le basi del linguaggio.

    Per chi ha postato, quello che scrivi fa capire che non hai le basi necessarie per affrontare quell'esercizio e l'unica cosa è studiare. Il libro suggerito è il minimo sindacale. Non c'è nulla di male sai cosa devi studiare e lo fai
  • Re: Crash..?

    Ok, Oregon. Apprezzo (davvero) il tono pacato col quale mi hai risposto, anche se condivido solo in parte il contenuto della risposta. Attendo comunque l'opinione del moderatore. Se confermerà che le cose stanno come hai riportato, ne ricaverò che qui non tira aria per me e smetterò di tediare lasciando questi lidi perché non offrono quello che mi sarei aspettato. Non è una colpa, è una caratteristica, ma occorre essere chiari e diretti (non acidi, però). Sono andato avanti per almeno quindici anni a divertirmi per i fatti miei quando ancora internet non era nelle mie disponibilità, posso agevolmente tornare "ai bei vecchi tempi" e continuare a divertirmi.
  • Re: Crash..?

    Via... su... un pò (con l'accento) di leggerezza... i forummmm e in generale internet non contano nulla, o meglio un eps^2.
    Non sei una sorta di "calimero", piccolo brutto e nero, ti suggerisco di "irrobustire" assai la pelle, perchè niente di 4 cavolate scritte su un forum, concretamente, inciderà sulla tua vita, nel bene e nel male.

    è un mero passatempo, non chissà quale Evento Fondamentale Della Vita, non cadere nell' "anoressia-bimbominkieska".

    vieni dileggiato perchè non sai praticamente nulla di informatica? non c'è niente di male, fregatene e tira dritto, è il consiglio migliore "di vita internettistica" che puoi seguire (fregartene).
    ---
    bene, riguardo al resto, come cerco (vanamente) di spiegare l'informatica NON è non solo "facile", ma spesso NEPPURE quello che il dilettante-junior-bimbominkia (e talvolta pure programmatore de noartri) crede.

    Dietro aspetti apparentemente banali c'è l'universo mondo.

    Lo so che si pensa che chiunque possa fare il programmatore, lo so che si pensa che dopo aver scritto un programmello da 10 righe si è diventati uno sviluppatore, so benissimo che dopo una lauretta (dove non si impara praticamente nulla di utile) si ritiene di essere il novello Bill Gates.

    So benissimo che dato un problema basta fare una ricerca google e tentare un qualche genere di copia-incolla che, magicamente, farà più o meno qualcosa.

    Mi rendo anche conto che c'è sempre una fase di niubberia, così come ci fu per me a suo tempo, dove "la penna è sotto il tavolo, la penna è sopra il tavolo" sono concetti difficili.

    Però bisogna anche rendersi conto che se ho impiegato 35 anni per imparare quello che so adesso, e supponendo di essere due volte più bravo di me (... e qui staremmo a livelli siderali, vabbè supponiamolo...) ci vogliono sempre 17,5 anni.

    Dato che, in realtà, la situazione è opposta (cioè nel mio "piccolo" sono molto, ma molto, ma proprio molto più bravo del programmatore-ingegnere-laureato-professore ordinario-preside di facoltà di ingegneria medio), allora puoi concludere che se vuoi da me uno spiegone-pippone dovrai trovare un argomento che sia interessante.

    Già il fatto che ti abbia scritto che rilasciare la memoria alla chiusura del programma non è un dogma dovrebbe essere sufficiente, per te, per darti da fare a indagare PERCHE'.
    Avrai così imparato qualcosa che il 99% dei forummisti ignora completamente, non perchè sia tonto, ma semplicemente perchè non sono davvero esperti.
    Così come io non sono un veterinario solo perchè mi piacciono i gatti.

    Quindi relax, non vale la pena di irritarsi per le cavolatine internet

    PS quindi ti STO effettivamente insegnando qualcosa, o meglio ti sto dando lo spunto per "muovere (figurativamente) il culo e IMPARARE qualcosa di utile"
Devi accedere o registrarti per scrivere nel forum
55 risposte