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

    [C++] - Aiuto ERRORE STACK con Vector di Vector

    Buonasera,
    c'è un programma che mi sta facendo impazzire anche se sono ancora solo al suo inizio.
    In pratica ho una classe che al suo interno contiene un vector di vector di oggetti Casella (classe definita da me)

    Il problema è che non riesco a inserire gli oggetti Casella nel vector di vector, poichè visual studio mi da il seguente errore "Unhandled exception" etc etc

    Non riesco a capire dove sia l'errore, mi aiutate?
    Alla fine il costruttore della classe Tabella deve solo creare una Tabella di zeri.

    Grazie

    I MIEI DUE HEADER FILE PER LE CLASSI

    Tabella
    codice:
    #include "Casella.h"
    #include <vector>
    #include <iostream>
    
    
    
    
    class Tabella
    {
    private:
    	int n;
    	std::vector<std::vector<Casella*>> *tabella = new std::vector<std::vector<Casella*>>();
    
    
    public:
    	
    	Tabella(int n); /*Crea Tabella di Default a 0*/
    	~Tabella();
    	void mostraSudoku();
    	void esisteSuRiga();
    	void esisteSuColonna();
    	void esisteInRegione();
    };
    
    
    /*Crea Tabella di Default a 0*/
    Tabella::Tabella(int n)
    {	
    	for (int i = 0; i < n; i++)
    	{
    		//for (int j = 0; j < n; j++)
    		//{
    			Casella *casella = new Casella(); //Il Costruttore di Default di Casella, genera numero=0 e fisso=false
    			tabella->at(i).push_back(casella); //sull'i-esimo vettore di vettore inseriamo in coda una Casella di valore 0
    		//}
    	}
    };
    
    
    Tabella::~Tabella()
    {
    	for (int i = 0; i < n; i++)
    	{
    		for (int j = 0; j < n; j++)
    		{
    			delete tabella->at(i).at(j); //sull'i-esimo vettore di vettore inseriamo in coda 0
    		}
    		tabella->at(i).clear(); //libera la memoria di ogni vettore 
    	}
    	delete &this->n;
    	delete tabella;
    	tabella->clear();
    
    
    }
    
    
    void Tabella::mostraSudoku()
    {
    	for (unsigned int i = 0; i < tabella->size(); i++)
    	{
    		for (unsigned int j = 0; j < tabella->at(i).size(); i++)
    		{
    			std::cout << tabella->at(i).at(j)->getNumero();
    		}
    		std::cout << std::endl;
    
    
    	}
    };
    codice:
    #ifndef _SUDOKU_
    #define _SUDOKU_
    
    
    #include <vector>
    #include <ctime>
    #include <cstdlib>
    
    
    class Casella {
    
    
    private:
    	int numero;
    	bool fisso; //Se è Numero Fisso = TRUE, se Numero Non Fisso = FALSE 
    
    
    public: 
    	Casella();
    	Casella(int numero);
    	~Casella();
    	void setNumero(int valore){ this->numero = numero; };
    	void setFisso(bool fisso){ this->fisso = fisso; };
    	int getNumero(){ return numero; };
    	bool getFisso(){ return fisso;  };
    };
    
    
    Casella::Casella(int numero){
    	this->numero = numero;
    	this->fisso = false;
    };
    
    
    Casella::Casella(){
    	this->numero = 0;
    	this->fisso = false;
    };
    
    
    Casella::~Casella(){
    	delete &this->numero;
    	delete &this->fisso;
    }
    
    
    
    
    
    
    
    
    #endif
    FILE CPP PER IL MAIN
    codice:
    
    
    
    #include "stdafx.h"
    #include "Tabella.h"
    #include <iostream>
    //#include "Tabella.h"
    
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int size = 0;
    	std::cout << "Inserisci il size di riga e colonna della Cella: " << std::endl;
    	std::cin >> size;
    	Tabella *tabella = new Tabella(size);
    	tabella->mostraSudoku();
    	system("PAUSE");
    	return 0;
    }

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Domanda: quanti elementi contiene tabella? Risposta: nemmeno uno.
    codice:
    std::vector<std::vector<Casella*>> *tabella = new std::vector<std::vector<Casella*>>();
    Corretto sarebbe:
    codice:
    std::vector<std::vector<Casella*>> *tabella = new std::vector<std::vector<Casella*>>(n);
    e nel costruttore di tabella:
    codice:
        for (int i = 0; i < n; i++) {
            tabella->at(i).resize(n);
            etc...
    Tuttavia non capisco perché devi complicarti la vita in questo modo con i puntatori (a meno che sia una precisa consegna).
    Più semplice sarebbe:
    codice:
    class Tabella
    {
    private:
        int n;
        std::vector<std::vector<Casella>>;
    
    
    public:
        
        Tabella(int nelem); /*Crea Tabella di Default a 0*/
        ~Tabella();
        void mostraSudoku();
        void esisteSuRiga();
        void esisteSuColonna();
        void esisteInRegione();
    };
    
    
    /*Crea Tabella di Default a 0*/
    Tabella::Tabella(int nelem) : n(nelem)
    {   
        tabella.resize(n);    
        for (int i = 0; i < n; i++)
        {
            // crea una riga di caselle usando il costruttore di default 
            tabella.at(i).resize(n);
        }
    };
    
    
    Tabella::~Tabella()
    {
        // niente da fare perché ci pensa in automatico il distruttore dei vector
    }
    
    ....
    int _tmain(int argc, _TCHAR* argv[])
    {
        int size = 0;
        std::cout << "Inserisci il size di riga e colonna della Cella: " << std::endl;
        std::cin >> size;
        Tabella tabella(size);
        tabella.mostraSudoku();
        system("PAUSE");
        return 0;
    }
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  3. #3
    grazie, ma a me serve anche che il vector di vector carichi oggetti di tipo Casella, che per defult sono inizializzati a zero e false quando si istanziano, creando così una matrice di 0 iniziale.

    ma poi scusa è necessario dare un size al vector dal momento che il loro size puo variare di volta in volta?

    P.S. il mio professore vuole che gli oggetti vengano istanziati dinamicamente con new;

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Non mi pare di aver visto nel codice da te postato la sezione per il riempimento di Casella, e al tuo codice mi sono attenuto.
    ma poi scusa è necessario dare un size al vector dal momento che il loro size puo variare di volta in volta?
    La size la stai passando tu nel costruttore di tabella (int n). Che poi tu faccia:
    codice:
    /*Crea Tabella di Default a 0*/
    Tabella::Tabella(int n)
    {   
        tabella->resize(n); 
        for (int i = 0; i < n; i++)
        {
            //for (int j = 0; j < n; j++)
            //{
                Casella *casella = new Casella(); //Il Costruttore di Default di Casella, genera numero=0 e fisso=false
                tabella->at(i).push_back(casella); //sull'i-esimo vettore di vettore inseriamo in coda una Casella di valore 0
            //}
        }
    };
    
    // oppure
    
    /*Crea Tabella di Default a 0*/
    Tabella::Tabella(int n)
    {   
        for (int i = 0; i < n; i++)
        {
            tabella->push_back(); 
            //for (int j = 0; j < n; j++)
            //{
                Casella *casella = new Casella(); //Il Costruttore di Default di Casella, genera numero=0 e fisso=false
                tabella->at(i).push_back(casella); //sull'i-esimo vettore di vettore inseriamo in coda una Casella di valore 0
            //}
        }
    };
    non cambia la sostanza: devi creare lo spazio per mettere gli elementi. E lo spazio è sempre n
    P.S. il mio professore vuole che gli oggetti vengano istanziati dinamicamente con new;
    Capisco. Diciamo che fa "strano" vedere allocare un vector, ma se le consegne sono queste non le discuto. Attento però che solo per chi fai una new devi far corrispondere una delete. Oltretutto le delete seguono un preciso ordine.
    codice:
        delete &this->n; // errore: n non è un puntatore!!
        delete tabella;  // ok, ma al posto sbagliato.
        tabella->clear(); // ok, ma al posto sbagliato
    corretto è:
    codice:
        tabella->clear(); // ok, ma inutile. Ci pensa delete tabella a pulire tutto.
        delete tabella;
    Lo stesso nel distruttore di Casella: numero e fisso NON sono puntatori. Niente delete.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  5. #5
    Quote Originariamente inviata da shodan Visualizza il messaggio
    codice:
        delete &this->n; // errore: n non è un puntatore!!
        delete tabella;  // ok, ma al posto sbagliato.
        tabella->clear(); // ok, ma al posto sbagliato
    se elimino la & mi da errore, se elimino il this o paura di non eliminare la n dell'oggetto corrente. sbaglio?

    corretto è:
    codice:
        tabella->clear(); // ok, ma inutile. Ci pensa delete tabella a pulire tutto.
        delete tabella;
    Lo stesso nel distruttore di Casella: numero e fisso NON sono puntatori. Niente delete.
    grazie, questa non la sapevo e mi hai tolto il primo dubbio, il secondo è, essendo tabella un vector, e addirittura un vector di vector, dovrei fare delete[] oppure delete[][] ?

    ti posto inoltre il codice che ho steso, adesso la matrice carica gli elementi, il problema è che non istanziavo un vector nuovo da aggiurere al vector di vector tabella ogni volta, davo per scontato che istanziando un vector di vector gia istanziasse in automatico una matrice. sono neofitissimo scusa. il problema ora è che quando vado a stampare, stampa solo la prima riga, i primi 4 zeri credo, ma poi va in stack overflow, non capisco credo di aver rispettato tutti i size.

    tu che dici? guarda

    codice:
    #include "Casella.h"#include <vector>
    #include <iostream>
    
    
    
    
    class Tabella
    {
    private:
    	int n;
    	std::vector<std::vector<Casella*>*> *tabella = new std::vector<std::vector<Casella*>*>();
    
    
    public:
    	
    	Tabella(int n); /*Crea Tabella di Default a 0*/
    	~Tabella();
    	void mostraSudoku();
    	void esisteSuRiga();
    	void esisteSuColonna();
    	void esisteInRegione();
    };
    
    
    /*Crea Tabella di Default a 0*/
    Tabella::Tabella(int n)
    {	
    	for (int i = 0; i < n; i++)
    	{
    		std::vector <Casella*> *vec = new std::vector<Casella*>();
    		tabella->push_back(vec);
    		std::cout << "creato sottovettore " << i << std::endl;
    	}
    
    
    	for (int i = 0; i < n; i++)
    	{
    		for (int j = 0; j < n; j++)
    		{
    			Casella *casella = new Casella(); //Il Costruttore di Default di Casella, genera numero=0 e fisso=false
    			tabella->at(i)->push_back(casella); //sull'i-esimo vettore di vettore inseriamo in coda una Casella di valore 0
    			std::cout << "inserita casella " << i <<" "<<j<< std::endl;
    		}
    	}
    
    
    };
    
    
    Tabella::~Tabella()
    {
    	for (int i = 0; i < tabella->size(); i++)
    	{
    		for (int j = 0; j < tabella->size(); j++)
    		{
    			delete tabella->at(i)->at(j); //sull'i-esimo vettore di vettore inseriamo in coda 0
    		}
    		tabella->at(i)->clear(); //libera la memoria di ogni vettore 
    	}
    	delete &this->n;
    	delete tabella;
    	tabella->clear();
    
    
    }
    
    
    void Tabella::mostraSudoku()
    {
    	unsigned int i;
    	for (i = 0; i < 4; i++)
    	{
    		unsigned int j;
    		for (j = 0; j < 4; i++)
    		{
    			std::cout << tabella->at(i)->at(j)->getNumero();
    		}
    		std::cout << std::endl;
    
    
    	}
    };

  6. #6
    scusami, sgamato l'errore , il ciclo for interno, incrementa i e non j, scusami

  7. #7
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Quote Originariamente inviata da lello82nap Visualizza il messaggio
    se elimino la & mi da errore, se elimino il this o paura di non eliminare la n dell'oggetto corrente. sbaglio?
    Forse mi sono spiegato male: quella
    codice:
    delete &this->n;
    è un ERRORE CATASTROFICO!
    Se fossi un insegnante e vedessi una cosa del genere uno zero barrato non lo leverei a nessuno.

    n
    è una variabile creata sullo stack. Non stai facendo una new su di essa e pertanto il programma può andare in tilt se forzi una delete.
    1° Postulato del C++ : solo sulle variabili puntatori su cui si esegue una new è lecito fare una delete.

    Per quanto riguarda il this è utile per identificare variabili e funzioni di classe, ma è rindondante (di solito non lo mette nessuno). Niente paura quindi.

    grazie, questa non la sapevo e mi hai tolto il primo dubbio, il secondo è, essendo tabella un vector, e addirittura un vector di vector, dovrei fare delete[] oppure delete[][] ?
    delete [] è riservata per array C. Vector non è un array C.
    Per come hai impostato ora il codice devi fare:
    codice:
    Tabella::~Tabella()
    {
        for (int i = 0; i < tabella->size(); i++)
        {
            // corretto è prendere la dimensione di ogni vector interno.
            for (int j = 0; j < tabella->at(i)->size(); j++)
            {
                // libera Casella*
                delete tabella->at(i)->at(j); //sull'i-esimo vettore di vettore inseriamo in coda 0
            }
            delete tabella->at(i); //libera la memoria di ogni vettore interno.
        }
        delete tabella;
    }
    ti posto inoltre il codice che ho steso, adesso la matrice carica gli elementi, il problema è che non istanziavo un vector nuovo da aggiurere al vector di vector tabella ogni volta, davo per scontato che istanziando un vector di vector gia istanziasse in automatico una matrice. sono neofitissimo scusa. il problema ora è che quando vado a stampare, stampa solo la prima riga, i primi 4 zeri credo,
    cambia:
    codice:
    Tabella::Tabella(int n)
    in
    codice:
    Tabella::Tabella(int n_elem) : n(n_elem)
    e fai:
    codice:
    void Tabella::mostraSudoku()
    {
        unsigned int i;
        for (i = 0; i < n; i++)
        {
            unsigned int j;
            for (j = 0; j < n; i++) // qui ci va j++ non i++. Lo stack overflow dipende da questo.
            {
                std::cout << tabella->at(i)->at(j)->getNumero();
            }
            std::cout << std::endl;
        }
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  8. #8
    mi hai dato dei consigli PREZIOSISSIMI!!!
    ti ringrazio molto!
    c'è modo di darti un punteggio in qualche modo su questo sito? non ci giro spesso.

    vorrei farti un'ultima domanda: dato che per il mio sudoku dovrò fare di volta in volta un controllo di riga, di colonna e di Regione per assicurarmi che il numero che voglio inserire non si trovi n stessa riga, colonna o riquadro, algoritmicamente sai darmi qualche idea su come sviluppare questi 3 metodi? x quello di riga e colonna non credo di avere problemi, quello che mi preoccupa è il ciclo for da fare per scorrere le singole regioni, credo di dover utilizare l'algebra modulare (operatore modulo %) ma non ho proprio idea di come indicizzare tale ciclo. can you help me? GRAZIE!!!

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.