Exit code 3 (not my return value, looking for source)

11,832

It appears this exit code was returned by MPIR(GMP) because it could not allocate a big amount of memory. It's a bit annoying that this was not in any of the documentation though.

Share:
11,832
nikaspran
Author by

nikaspran

Updated on June 04, 2022

Comments

  • nikaspran
    nikaspran almost 2 years

    Greetings,

    my program exits with the code 3. No error messages, no exceptions, and the exit is not initiated by my code.

    The problem occurs when I am trying to read extremely long integer values from a text file (the text file is present and correctly opened, with successful prior reading).

    I am using very large amounts of memory (in fact, I think that this might be the cause, as I am nearly sure I go over the 2GB per process memory limit). I am also using the GMP (or, rather, MPIR) library to multiply bignums. I am fairly sure that this is not a file I/O problem as I got the same error code on a previous program version that was fully in-memory.

    System:
    MS Visual Studio 2008
    MS Windows Vista Home Premium x86
    MPIR 2.1.0 rc2
    4GB RAM

    Where might this error code originate from?

    EDIT: this is the procedure that exits with the 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: completely in-memory version that also exits with 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;
    }