Output diversi dopo il debug e la compilazione di programmi C++
-
22-09-2019 - |
Domanda
Sto eseguendo CodeBlocks sul compilatore MingW in una macchina virtuale XP.Ho scritto in un codice semplice, accessibile su cl1p , che risponde alla domanda dell'algoritmo su CodeChef (Beh, la risposta è solo in parte, poiché non ho ancora incluso il ciclo per più casi di test.
Tuttavia, il mio problema è che durante l'esecuzione in modalità debug, fornisce l'output corretto di 5, per l'input:
3
1
2 1
1 2 3
Tuttavia, quando lo costruisco e lo eseguo, dà l'assurdo, enorme output 131078, quello che mi sembra spazzatura.Non capisco come diavolo stia succedendo, ma immagino che abbia qualcosa a che fare con l'allocazione dinamica della memoria.Qual è il problema qui e come posso risolverlo?L'ho anche eseguito tramite il compilatore online su BotSkool, e ha funzionato bene.Dopo aver aggiunto il ciclo per i casi di test, il codice ha funzionato correttamente anche su CodeChef!
#include <iostream>
using namespace std;
int main()
{
// Take In number of rows
int numofrows;
cin >> numofrows;
// Input Only item in first row
int * prevrow;
prevrow = new int[1];
cin >> prevrow[0];
// For every other row
for (int currownum = 1; currownum < numofrows; currownum++)
{
// Declare an array for that row's max values
int * currow;
currow = new int[currownum+1];
int curnum;
cin >> curnum;
// If its the first element, max is prevmax + current input
currow[0] = prevrow[0] + curnum;
// for every element
int i = 1;
for (; i <= currownum; i++)
{
cin >> curnum;
// if its not the first element, check whether prevmax or prev-1max is greater. Add to current input
int max = (prevrow[i] > prevrow[i-1]) ? prevrow[i] : prevrow[i-1];
// save as currmax.
currow[i] = max + curnum;
}
// save entire array in prev
prevrow = new int[i+1];
prevrow = currow;
}
// get highest element of array
int ans = 0;
for (int j=0; j<numofrows; j++)
{
if (prevrow[j] > ans)
{
ans = prevrow[j];
}
}
cout << ans;
}
Soluzione
Per prima cosa, in questo modo:
//save entire array in prev
prevrow = new int [i+1];
prevrow = currow;
copia il puntatore, non l'intero array.
Altri suggerimenti
Esegui il codice tramite Valgrind su una macchina Linux e rimarrai stupito da quanti punti il tuo codice perde memoria.Se stai intraprendendo la strada difficile della gestione della memoria, fallo bene ed "elimina" tutta la memoria appena allocata prima di allocarne altra.Se invece preferisci la strada facile, usa un std::vettoriale e dimentica la gestione della memoria.
Nel vostro ciclo, si ha questa linea
int max = (prevrow[i]>prevrow[i-1])?prevrow[i]:prevrow[i-1];
Nella prima iterazione del ciclo principale, quando currownum == 1
, sarà inserito l'anello contenente questa linea, come i
viene inizializzato a 1
. Ma la prima iterazione, prevrow
ha un solo elemento e questa linea tenta di accedere prevrow[1]
. In una build di debug, la memoria semplicemente viene inizializzato a zero, ma in una corporatura normale, si ottiene un valore spazzatura che è capitato di essere nella memoria, che porta al risultato che si vede.
Praticamente sempre, quando si arriva valori della spazzatura in una corporatura normale, ma tutto va bene in una build di debug, si accede a un po 'di memoria non inizializzata.
Inoltre, il programma perde la memoria come un matto. Ad esempio, non è necessario assegnare qualsiasi risultato new
all'interno del ciclo di prevrow
perché subito dopo aver modificato prevrow
per puntare a un altro blocco di memoria allocata. Inoltre, si dovrebbe chiamare delete
per qualsiasi memoria che non sono più in uso.