1

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;
}
nikaspran
  • 312
  • 1
  • 3
  • 10
  • Do you know which line it exits from? Can we see some code? – tzaman Jun 06 '10 at 17:41
  • I am not exactly sure where the exit happens precisely, however, I have pasted the function responsible. It's problematic to trace it as this happens at the end of about 3-4 hrs of computation time. – nikaspran Jun 06 '10 at 17:49
  • The error code points at file IO, according to [this](http://msdn.microsoft.com/en-us/library/ms681382%28v=VS.85%29.aspx). Could be indirect though; have you tried running this code on something [like valgrind](http://stackoverflow.com/questions/413477/is-there-a-good-valgrind-substitute-for-windows), could be that a FILE struct is getting clobbered by an out of bounds write, a danger with GMP. – academicRobot Jun 06 '10 at 19:26
  • Unfortunately, I got the same exit code when I tried to run a completely in-memory implementation of the same process (I have posted code of that function). – nikaspran Jun 06 '10 at 19:33
  • Sorry, my point was really the second part of my comment; have you tried checking for out of bounds memory reads/writes? These can often lead to delayed, very random seeming errors. (Not a segfault unless it accesses outside application memory, and since your using so much, most memory is in the application.) – academicRobot Jun 06 '10 at 20:16

1 Answers1

0

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.

nikaspran
  • 312
  • 1
  • 3
  • 10