[C] Memory error

Messaggioda jarrod » 05/02/2018, 11:32

l'alfabeto farfallino è un gioco linguistico per bambini che consiste nel raddoppiare ogni vocale con l'aggiunta di una f interposta. quindi ciao diventa 'cifiafaofo'. Io devo fare un programma al contrario, cioè prendo una stringa tipo 'cifiafaofo' e deve ritornare una stringa allocata contenente 'ciao'.
Il mio main.c è questo:
Codice:
#include "farfallino.h"

int main(){

   char str1[] = "afaifiufuofolafa";
   
   char *ris = farfallino_decode(str1);


   return 0;


}


il mio file.h è:
Codice:
#if !defined FARFALLINO_H
#define FARFALLINO_H
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>

extern char *farfallino_decode(const char *s);



#endif

il mio file.c è:
Codice:
#include "farfallino.h"

char *farfallino_decode(const char *s){

   size_t lung = strlen(s);
   size_t len = 0;
   char prova = 0;
   char *c = &prova;

   if (s == NULL){
      return NULL;
   }


   for (size_t k = 0; k < lung; k++){
      if (s[k] == 'a' && s[k + 1] == 'f' && s[k + 2] == 'a'){
         len++;
         c = realloc(c, len * sizeof(char));
         c[k] = 'a';
         k += 3;
      }
      else if (s[k] == 'e' &&s[k + 1] == 'f' &&s[k + 2] == 'e'){

         len++;
         c = realloc(c, len * sizeof(char));
         c[k] = 'e';
         k += 3;


      }

      else if (s[k] == 'i' &&s[k + 1] == 'f' && s[k + 2] == 'i'){
         len++;
         c = realloc(c, len * sizeof(char));
         c[k] = 'i';
         k += 3;
      }

      else if (s[k] == 'o' &&s[k + 1] == 'f' && s[k + 2] == 'o'){
         len++;
         c = realloc(c, len * sizeof(char));
         c[k] = 'o';
         k += 3;
      }

      else if (s[k] == 'u' && s[k + 1] == 'f' &&s[k + 2] == 'u'){

         len++;
         c = realloc(c, len * sizeof(char));
         c[k] = 'u';
         k += 3;
      }

      else{
         len++;
         c = realloc(c, len * sizeof(char));
         c[k] = s[k];
      }
   }

   free(c);
   return c;

}

Non capisco perchè mi da Memory error, qualcuno ha capito perchè?
jarrod
Junior Member
Junior Member
 
Messaggio: 125 di 358
Iscritto il: 26/02/2017, 13:23

Re: [C] Memory error

Messaggioda apatriarca » 05/02/2018, 13:27

Stai provando a fare il realloc su una stringa allocata staticamente (in effetti un singolo char). Il modo corretto per farlo è piuttosto assegnare NULL a c e usare il fatto che realloc alloca il blocco di memoria se questo è NULL. Ma non ha alcun senso allocare la stringa un carattere per volta. Considerando che l'allocazione di memoria è tra le operazioni computazionalmente più costose che puoi fare senza passare all'uso di file o reti o .., ha molto più senso allocare una stringa uguale all'input e se proprio abbiamo bisogno di quella poca memoria aggiuntiva* puoi sempre reallocare alla fine.

Poteva aver senso non allocare tutta la stringa nel caso in cui non avessi calcolato la lunghezza. Potevi infatti implementare il codice senza bisogno di calcolarla come segue (input e output sono già allocati per comodità). Puoi ignorare il restrict e lo static se non sai cosa sono. Significano in pratica che i due puntatori non sono NULL e che fanno riferimento a blocchi di memoria disgiunti.
Codice:
bool farfallino_decode(char dest[restrict static 1], const char src[restrict static 1])
{
    int i = 0;
    int j = 0;

    while (src[i] != '\0')
    {
        if (strchr("aeiou", src[i]) != NULL) {
            if (src[i+1] == 'f' && src[i+2] == src[i]) {
                dest[j++] = src[i];
                i += 2;
            } else {
                return false;
            }
        } else {
            dest[j++] = src[i++];
        }
    }

    return true;
}


* Nota comunque che a livello di sistema stai probabilmente allocando "grossi" blocchi (qualche KB) e che il tuo sistema può probabilmente allocare facilmente qualche GB di dati. Sprecare qualche byte non è certamente la fine del mondo.
apatriarca
Moderatore
Moderatore
 
Messaggio: 4953 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [C] Memory error

Messaggioda Super Squirrel » 05/02/2018, 17:09

Oltre a quanto detto da apatriarca, credo ci sia un altro errore nella funzione "farfallino_decode". Non sono molto pratico con la sintassi del C, ma mi sembra di capire che deallochi la memoria prima del return!

Io cmq farei qualcosa del genere:

Codice:
#include <iostream>

unsigned int get_len(const char *str)
{
    unsigned int len = 0;
    while(str[len] != '\0')
    {
        ++len;
    }
    return len;
}

char *farfallino_decode(char *str)
{
    unsigned int len = get_len(str);
    if(len < 3)
    {
        return str;
    }
    char *str_2 = new char[len + 1];
    unsigned int j = 0;
    for(unsigned int i = 0; i < len; i++)
    {
        if(i != 0 && i != len - 1 && str[i] == 'f' && (str[i - 1] == 'a' || str[i - 1] == 'e' || str[i - 1] == 'i' || str[i - 1] == 'o' || str[i - 1] == 'u') && str[i - 1] == str[i + 1])
        {
            ++i;
        }
        else
        {
            str_2[j++] = str[i];
        }
    }
    str_2[j] = '\0';
    return str_2;
}

int main()
{
    char str_1[] = "afaifiufuofolafa";
    char *str_2 = farfallino_decode(str_1);
    std::cout << str_2;
    delete[] str_2;
}
Chi dorme in democrazia, si sveglia in dittatura.
Super Squirrel
Senior Member
Senior Member
 
Messaggio: 159 di 1486
Iscritto il: 16/05/2013, 22:05

Re: [C] Memory error

Messaggioda apatriarca » 05/02/2018, 17:18

@Super Squirrel: Non è poi tanto diverso rispetto al C++ (anche se ci sono funzionalità che sono specifiche di entrambi). Hai ragione riguardo alla deallocazione. Va fatta nel main o la memoria non sarà accessibile. Ma devo ammettere di essermi fermato alle prime righe nella lettura. La logica della funzione è anche molto più complicata del necessario.
apatriarca
Moderatore
Moderatore
 
Messaggio: 4954 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [C] Memory error

Messaggioda jarrod » 05/02/2018, 20:54

ok capito. Grazie mille!
jarrod
Junior Member
Junior Member
 
Messaggio: 126 di 358
Iscritto il: 26/02/2017, 13:23


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite