2010-06-06 3 views
1

Salutations,Code de sortie 3 (pas ma valeur de retour, à la recherche de la source)

mon programme se termine avec le code 3. Aucun message d'erreur, sans exception, et la sortie n'est pas initié par mon code.

Le problème se produit lorsque j'essaie de lire des valeurs entières extrêmement longues à partir d'un fichier texte (le fichier texte est présent et correctement ouvert, avec une lecture préalable réussie). J'utilise de très grandes quantités de mémoire (en fait, je pense que cela pourrait être la cause, car je suis presque sûr que je dépasse la limite de 2 Go par mémoire de processus). J'utilise aussi la bibliothèque GMP (ou plutôt MPIR) pour multiplier les bignums. Je suis assez sûr que ce n'est pas un problème d'E/S de fichier car j'ai eu le même code d'erreur sur une version précédente du programme qui était entièrement en mémoire.

Système:
MS Visual Studio 2008
MS Windows Vista Édition Familiale Premium x86
MRIP 2.1.0 RC2
4 Go de RAM

Si ce code d'erreur peut provenir?

EDIT: c'est la procédure qui sort avec le code

void condenseBinSplitFile(const char *sourceFilename, int partCount){ 
//condense results file into final P and Q 
std::string tempFilename; 
std::string inputFilename(sourceFilename); 
std::string outputFilename(BIN_SPLIT_FILENAME_DATA2); 
mpz_class *P = new mpz_class(0); 
mpz_class *Q = new mpz_class(0); 
mpz_class *PP = new mpz_class(0); 
mpz_class *QQ = new mpz_class(0); 
FILE *sourceFile; 
FILE *resultFile; 

fpos_t oldPos; 
int swapCount = 0; 
while (partCount > 1){ 
    std::cout << partCount << std::endl; 
    sourceFile = fopen(inputFilename.c_str(), "r");  
    resultFile = fopen(outputFilename.c_str(), "w"); 
    for (int i=0; i<partCount/2; i++){ 
     //Multiplication order: 
     //Get Q, skip P 
     //Get QQ, mul Q and QQ, print Q, delete Q 
     //Jump back to P, get P 
     //Mul P and QQ, delete QQ 
     //Skip QQ, get PP 
     //Mul P and PP, delete P and PP 

     //Get Q, skip P 
     mpz_inp_str(Q->get_mpz_t(), sourceFile, CALC_BASE); 
     fgetpos(sourceFile, &oldPos); 
     skipLine(sourceFile); 
     skipLine(sourceFile); 

     //Get QQ, mul Q and QQ, print Q, delete Q 
     mpz_inp_str(QQ->get_mpz_t(), sourceFile, CALC_BASE);  
     (*Q) *= (*QQ); 
     mpz_out_str(resultFile, CALC_BASE, Q->get_mpz_t()); 
     fputc('\n', resultFile); 
     (*Q) = 0; 

     //Jump back to P, get P 
     fsetpos(sourceFile, &oldPos); 
     mpz_inp_str(P->get_mpz_t(), sourceFile, CALC_BASE); 

     //Mul P and QQ, delete QQ 
     (*P) *= (*QQ); 
     (*QQ) = 0; 

     //Skip QQ, get PP 
     skipLine(sourceFile); 
     skipLine(sourceFile); 
     mpz_inp_str(PP->get_mpz_t(), sourceFile, CALC_BASE); 
     //Mul P and PP, delete PP, print P, delete P    
     (*P) += (*PP); 
     (*PP) = 0; 
     mpz_out_str(resultFile, CALC_BASE, P->get_mpz_t()); 
     fputc('\n', resultFile); 
     (*P) = 0; 
    } 
    partCount /= 2; 

    fclose(sourceFile); 
    fclose(resultFile); 

    //swap filenames 
    tempFilename = inputFilename; 
    inputFilename = outputFilename; 
    outputFilename = tempFilename; 
    swapCount++; 
} 

delete P; 
delete Q; 
delete PP; 
delete QQ; 

remove(BIN_SPLIT_FILENAME_RESULTS); 
if (swapCount%2 == 0) 
    rename(sourceFilename, BIN_SPLIT_FILENAME_RESULTS); 
else 
    rename(BIN_SPLIT_FILENAME_DATA2, BIN_SPLIT_FILENAME_RESULTS); 
} 

EDIT2: complètement en mémoire la version qui sort également avec 3

void binarySplitE(const ULONG first, const ULONG last, mpz_class *P, mpz_class *Q){ 
//P(first, last) = P(first, mid)*Q(mid, last) + P(mid, last) 
//Q(first, last) = Q(first, mid)*Q(mid, last) 
if (last - first == 1){ 
    calcP(P, first, last); 
    calcQ(Q, first, last); 
    return; 
} 

ULONG mid = (first+last)/2; 
mpz_class *PP = new mpz_class(*P); 
mpz_class *QQ = new mpz_class(*Q); 
//Calculate P(first, mid) and Q(first, mid) 
binarySplitE(first, mid, P, Q); 
//Calculate P(mid, last) and Q(mid, last) 
binarySplitE(mid, last, PP, QQ); 

//P(first, last) == P(first, mid) 
*P *= (*QQ); 
//P(first, last) == P(first, mid)*Q(mid, last) 
*P += (*PP); 
//P(first, last) == P(first, mid)*Q(mid, last) + P(mid, last); 

//Q(first, last) == Q(first, mid) 
*Q *= (*QQ); 
//Q(first, last) == Q(first, mid)*Q(mid, last) 

delete PP; 
delete QQ; 
} 
+0

Savez-vous de quelle ligne il sort? Pouvons-nous voir du code? – tzaman

+0

Je ne suis pas sûr exactement où la sortie se produit avec précision, cependant, j'ai collé la fonction responsable. Il est problématique de le tracer car cela se produit à la fin d'environ 3-4 heures de temps de calcul. – nikaspran

+0

Le code d'erreur pointe sur le fichier IO, conformément à [this] (http://msdn.microsoft.com/en-us/library/ms681382%28v=VS.85%29.aspx). Peut être indirect cependant; avez-vous essayé d'exécuter ce code sur quelque chose [comme valgrind] (http://stackoverflow.com/questions/413477/is-there-a-good-valgrind-substitute-for-windows), peut-être qu'un struct FILE obtient bousculé par un hors limites écrire, un danger avec GMP. – academicRobot

Répondre

0

Il semble que ce code de sortie a été retourné par MRIP (GMP) car il ne pouvait pas allouer une grande quantité de mémoire. C'est un peu ennuyeux que ce n'était pas dans la documentation cependant.

+0

Vous pouvez toujours vérifier ce http://www.opengroup.org/onlinepubs/000095399/functions/perror. html crache dans ces cas. –

Questions connexes