Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    [C++] Puntatori, Array e Attributi

    Salve,
    sto cercando di fare una classe in C++ per trattare immagini. Tale classe ha 5 attributi privati:

    - Type: identifica il tipo di immagine
    - Row: identifica il numero di righe dell'immagine
    - Col: identifica il numero di colonne
    - Maxval: identifica il valore massimo di ciascun pixel (solitamente 255)
    - Data: è un array (o meglio un puntatore ad array) che contiene i livelli di grigio di ciascun pixel

    Di seguito posto i tre file (il file .h per l'header della classe, il file .cpp per la classe ed il file .cpp per testare la classe)

    codice:
    //File MyImage.h
    #ifndef MYIMAGE_H#define MYIMAGE_H
    #include <sstream>
    using namespace std;
    
    
    class MyImage
    {
            string type;
            int row;
            int col;
            int maxval;
            int* data;
    
    
        public:
            MyImage();
            MyImage(int r, int c);
            MyImage(string nomefile);
            ~MyImage();
            bool Open(string nomefile);
            bool Save(string nomefile);
    };
    
    
    #endif
    codice:
    //File MyImage.cpp
    #include "MyImage.h"
    #include <fstream>
    #include <iostream>
    #include <string>
    using namespace std;
    
    
    MyImage::MyImage() {
    }
    
    
    MyImage::MyImage(int r, int c) {
        row = r;
        col = c;
    }
    
    
    MyImage::MyImage(string nomefile) {
        type = nomefile;
    }
    
    
    MyImage::~MyImage() {
        delete data;
    }
    
    
    bool MyImage::Open(string nomefile) {
        ifstream image(nomefile.c_str());
        image>>type;
        image>>col;
        image>>row;
        image>>maxval;
    
    
        int pixel[col*row];
        for (int i=0; i<col*row; i++)
        {
            int num;
            image>>num;
            pixel[i] = num;
        }
        data=pixel;
        image.close();
        return true;
    }
    
    
    bool MyImage::Save(string nomefile) {
        ofstream image(nomefile.c_str());
        image<<type<<endl;
        image<<col<<endl;
        image<<row<<endl;
        image<<maxval<<endl;
    
    
        for (int i=0; i<col*row; i++)
        {
            int num = data[i];
            image<<num<<endl;
        }
        image.close();
        return true;
    }
    codice:
    #include "MyImage.h"
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    
    int main() {
        MyImage a;
        a.Open("im0.pgm");
        a.Save("im.pgm");
    
        return(0);
    }
    Il problema è essenzialmente con l'attributo "data" che, come detto, dovrebbe essere un puntatore ad un array. Infatti quando nel main provo la classe (per ora carico un'immagine e la salvo con un'altro nome) durante il metodo Open "data" contiene i valori esatti mentre durante il metodo Save "data" contiene valori del tutto sballati... come se nel metodo precedente venisse cancellato ciò che era stato salvato nell'attributo.

    Qualcuno saprebbe aiutarmi?


    PS: spero che nel codice non ci sia troppa spazzatura... infatti la devo ancora sistemare e potrebbero esserci scritte cose strane in mezzo XD

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Non puoi scrivere

    data=pixel;

    perché pixel è locale e non esiste più dopo il metodo.

    Devi allocare dinamicamente il vettore usando il puntatore data e memorizzare in quel vettore i dati che leggi.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Quote Originariamente inviata da oregon Visualizza il messaggio
    Non puoi scrivere

    data=pixel;

    perché pixel è locale e non esiste più dopo il metodo.

    Devi allocare dinamicamente il vettore usando il puntatore data e memorizzare in quel vettore i dati che leggi.
    Immaginavo ci fosse un problema di questo tipo e sto cercando di leggere un po' di guide online però non riesco a risolvere. Sto infatti provando ad allocare il vettore nel costruttore però il problema è che quando creo l'oggetto MyImage non è detto che io sappia già quanto dovrà essere grande... per cui non so quanto spazio devo allocare.

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Allocalo quando conosci le dimensioni.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Tra l'altro, non puoi usare semplicemente un std::vector<int> per data, usando la resize() opportunamente? Ti eviti un sacco di rogne legate alla gestione del lifetime dell'array...
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Mi limito a suggerire aggiustamenti del codice proposto perché, la maggior parte delle volte, sono esercizi il cui ambito è limitato agli argomenti studiati e non effettive necessità di professionisti a cui si può suggerire un metodo più avanzato.

    Ma ovviamente, se le cose non stanno così in questo caso, ovviamente un vector di C++ è più adatto a risolvere il problema.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Si infatti, questo proposto è un esercizio che devo fare per l'università (e fra l'altro ho un'altra difficoltà... ma ne parlerò in un'altro post) e quindi è mirato per sviluppare certi argomenti. Fra l'altro queste sono le prime righe di codice che butto giù in C++ per cui qualsiasi consiglio è ben accetto.

    Ad ogni modo ho risolto il problema dell'allocamento dinamico inserendo
    codice:
    data = new int[col*row];
    all'interno del metodo Open come mi dicevi tu oregon.

  8. #8
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Corretto, ma a questo punto devi fare attenzione al fatto che la Open potrebbe essere usata più di una volta e la Save addirittura prima della Open ... quindi è necessario qualche controllo sul puntatore prima di utilizzarlo, e magari una sua inizializzazione a NULL nel costruttore.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

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 © 2025 vBulletin Solutions, Inc. All rights reserved.