Home > OS >  Realloc throws stack overflow sporadically in program that calculates large integers
Realloc throws stack overflow sporadically in program that calculates large integers

Time:11-06

void inf_int::Sub(const char num, const unsigned int index)
{

    if (this->length < index) {
        char* tmp = (char*)realloc(this->digits, index   1);
        if (tmp == NULL) {
            cout << "Memory reallocation failed, the program will terminate." << endl;
            free(this->digits);// provided that the destructor does not call free itself
            exit(0);
        }

        this->digits = tmp;
        
        this->length = index;                   
        this->digits[this->length] = '\0';  
    }


    if (this->digits[index - 1] < '0') {    
        this->digits[index - 1] = '0';
    }

    this->digits[index - 1] -= num   '0';   


    if (this->digits[index - 1] < '0') {    
        this->digits[index - 1]  = 10;  
        Sub('1', index   1);            
    }

}

I am trying to make a program that calculates really large integers, using character arrays to store each digit. The compiler keeps throwing overflow error in char* tmp = (char*)realloc(this->digits, index 1); after 2 or so debugs, then after throwing errors for a few times, works again for another two tries, then repeats. Can anybody point out where I am doing wrong? Thank you.

digits is char* digits;

inf_int::inf_int()
{

    this->digits = new char[2]; 
    this->digits[0] = '0';      
    this->digits[1] = '\0';
    this->length = 1;
    this->thesign = true;
}

inf_int::inf_int(int n) {
    char buf[100];

    if (n < 0) {        
        this->thesign = false;
        n = -n;
    }
    else {
        this->thesign = true;
    }

    int i = 0;
    while (n > 0) {         
        buf[i] = n % 10   '0';

        n /= 10;
        i  ;
    }

    if (i == 0) {   
        new (this) inf_int();   
    }
    else {
        buf[i] = '\0';
        this->digits = new char[i   1];
        this->length = i;
        strcpy(this->digits, buf);
    }
}
inf_int::inf_int(const char* str)
{
    char* answer = new char[strlen(str)];
    
    if (str == NULL) {
        new (this) inf_int();
    }
    else {
        strcpy(answer, str);
        
        
        if (answer[0] == '-') {
            char* solution = new char[strlen(str)];
            this->thesign = false;
            for (unsigned int i = 1; i < strlen(str); i  ) {
                solution[strlen(str) -1-i] = answer[i];
            }
            solution[strlen(str)] = '\0';
            this->digits = new char[strlen(str) 1 ];
            this->length = strlen(str);
            strcpy(this->digits, solution);
        }

        else {
            char* solution = new char[strlen(str) 1];;
            this->thesign = true;//123 3

            for (unsigned int i = 0; i < strlen(str); i  ) {
           
                solution[strlen(str)  - i-1] = answer[i];
            }
            solution[strlen(str)] = '\0';
            this->digits = new char[strlen(str) 1 ];
            this->length = strlen(str);
            strcpy(this->digits, solution);
        }
    }
    }

CodePudding user response:

this->digits = new char[2]; 

This class member is initially allocated using new.

char* tmp = (char*)realloc(this->digits, index   1);

This is undefined behavior. realloc is for C code that used malloc to allocate memory. A realloc of something that was originally newed always ends in tears. Everything that follows from this point on is undefined behavior.

new (this) inf_int();

including this, which does not accomplish anything useful, except more undefined behavior (for completely different reasons).

It seems that, based on the entirety of the shown code, it was likely stitched together from the results of multiple keyword searches, from some search engine, instead of applying knowledge that was acquired from studying with a C textbook. This approach to writing C code rarely produces working results; additionally modern C rarely needs to use new for basic logic of the kind shown here, instead C 's containers handle all the memory allocation for you, and correctly. For example, std::vector does pretty much what a good portion of this code is trying to accomplish -- allocating an initial buffer and resizing it, when needed. This is exactly what std::vector is for, and more information on how to use it will be found in your favorite C textbook.

  • Related