Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2017
    Messaggi
    3

    Problema puntatori linguaggio C

    Buonasera a tutti,
    sono nuovo qui sul forum dato che ho iniziato da poco a programmare siccome devo affrontare l'esame di Fondamenti di Informatica a breve.
    Ho un problema con un esercizio: il testo mi chiede di scrivere un programma che permetta all'utente di scrivere una parola (o comunque una sequenza di caratteri, max 100), di seguito il programma dovrà visualizzare a schermo quante volte compaiono le lettere nella parola scritta(per esempio, inserita la parola "cassa", il programma dovrà visualizzare a schermo che la lettera "c" compare una volta sola, la lettera "s" invece due volte, ecc.).

    Ho strutturato il programma in modo che una volta inserita la parola, ne vengano contati i caratteri tramite la funzione strlen, il tutto memorizzato in una variabile intera.
    Successivamente richiamo una funzione che mi restituisci un puntatore: tale puntatore riconduce ad un array, che ha le stesse dimensioni dell'array che contiene la parola inserita.
    La funzione che ho scritto in teoria dovrebbe permettermi di confrontare ogni cella dell'array contenente la parola con le altre celle, inclusa se stessa. Ogni volta che due celle risultano identiche, il valore della cella dell'array "vettore_numerativo[NUM]" corrispondente alla posizione della lettera in esame viene aumentato di 1, mi spiego: inserendo la parola "ciao", in teoria la funzione dovrebbe confrontare una per una le lettere tra di loro, a partire dalla prima. Quindi, la funzione prende la lettera "c" e la confronta con se stessa, con "i", con "a" e con "o", poi prende la lettera "i" e ripete il ciclo. Ogni volta che due lettere risultano identiche, la cella dell'array "vettore_numerativo[NUM]" corrispondente alla posizione della lettera esaminata, viene incrementata di 1.

    Il programma è questo:

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX_LET 100
    
    int *cardinalitalettere(char *p, int NUM) {
        int i, k, t;
        int vettore_numerativo[NUM];
        int *v;
        v = vettore_numerativo;
        for (t = 0; t < NUM; t++) {
            v[t] = 0;
        }
        for (i = 0; i < NUM; i++) {
            for(k = 0; k < NUM; k++) {
                if (p[i] == p[k]) {
                    v[i] = v[i] + 1;
                }
            }
        }
        return v;
    }
                    
    
    
    int main() {
        char s[MAX_LET];
        int NUM, i;
        int *c;
        printf("Inserire una frase composta sia da lettere minuscole che maiuscole, con al massimo %d caratteri:\n", MAX_LET);
        scanf("%s", s);
        NUM = strlen(s);
        c = cardinalitalettere(s, NUM);
        printf("La numerosità delle lettere nella parola inserita è la seguente:\n");
        for (i = 0; i < NUM; i++) {
            printf("%c --> %d\n", s[i], c[i]);
            printf("\n");
        }
        return 0;
    }
    Il problema è che, una volto che lo eseguo, i valori che restituisce la funzione sono sballati e anche randomici, nel senso che eseguendo più volte il programma ed immettendo sempre la stessa parola, vengono stampati a schermo valori sempre differenti tra di loro.
    Due esempi:

    codice:
    Inserire una frase composta sia da lettere minuscole che maiuscole, con al massimo 100 caratteri:
    ciao
    La numerosità delle lettere nella parola inserita è la seguente:
    c --> 0
    
    i --> 0
    
    a --> 1279985408
    
    o --> 32766
    codice:
    Inserire una frase composta sia da lettere minuscole che maiuscole, con al massimo 100 caratteri:
    ciao
    La numerosità delle lettere nella parola inserita è la seguente:
    c --> 0
    
    i --> 0
    
    a --> -1997601392
    
    o --> 32764
    L'ho riguardato più volte ma non riesco a capire dov'è l'errore.
    Se poteste aiutarmi mi sareste di grande aiuto.
    Grazie in anticipo,

    Samuele

  2. #2
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626
    Non dovresti mai restituire il puntatore di una variabile definita nello stack, perchè potrebbe non avere più i valori che ti aspetti una volta terminata la funzione. In questo caso creala nell'heap (e ricordati di liberarne la memoria):
    codice:
    int *cardinalitalettere(char *p, int NUM) {
         int i, k, t;
         //int vettore_numerativo[NUM];
         //v = vettore_numerativo;
         int *v = (int*)malloc(sizeof(int) * NUM);
         ...
    }
    
    int main(){
      ...
      free(c);
      return 0;
    }

  3. #3
    Utente di HTML.it
    Registrato dal
    Jan 2017
    Messaggi
    3
    Perdonami se ti rispondo soltanto ora ma sono andato ad informarmi per quanto riguarda le funzioni free e malloc dato che non ho ancora avuto modo di studiarle. In pratica credo si tratti di un problema di allocazione dinamica della memoria.
    Dimmi se ho capito bene: se definisco, in una funzione diversa dal main (per esempio int f(int a), una variabile che viene restituita al termine della funzione, quando chiamo la suddetta funzione nel main, mi viene restituito il valore assunto dalla variabile definita nella funzione int f(int a), senza nessun problema. Invece, se tale funzione restituisce un puntatore ad una variabile(ancora una volta definita nella funzione esterna al main), stampando il valore puntato dal puntatore potrei ritrovarmi dei valori diversi da quelli corretti, questo perchè non ho allocato memoria dinamica tramite la funzione malloc.
    Inoltre, una volta che il programma termina, mi devo ricordare di liberare lo spazio di memoria occupata dal puntatore tramite la funzione free.
    E' corretto ciò che ho detto?

    Quindi, quando definisco una funzione che mi restituisce un puntatore devo sempre allocare memoria dinamica tramite la funzione malloc?

    Ultima cosa: il (int*) anteposto al malloc serve per convertire il valore restituito dalla funzione malloc ad un int, dato che malloc dovrebbe restituire un char, giusto?

    Grazie ancora!
    Ultima modifica di QuickSL; 08-01-2017 a 13:41

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Non è proprio come hai scritto ...

    La questione è che il puntatore che restituisci indica un indirizzo di una zona di memoria dove c'è il dato che ti interessa.

    Se questa zona punta allo stack (dato che punta a variabili locali ad una funzione), essendo quest'area distrutta alla fine della funzione, il tuo dato lo sarà di conseguenza e il puntatore inutile.

    Una soluzione è far puntare il puntatore ad un'area (detta heap) che viene trattata in maniera diversa e che non viene eliminata automaticamente alla fine della funzione ma solo esplicitamente con la free.

    Sembra che tutti questi concetti tu non li conosca ancora, quindi mi sembra che sia necessario per te attendere un po' e studiare con calma dai libri con metodo, altrimenti rischi di fare una gran confusione.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente di HTML.it
    Registrato dal
    Jan 2017
    Messaggi
    3
    Si lo penso anche io, grazie comunque per la risposta!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.