Search code examples
arrayscchardynamic-memory-allocation

Calculating sum of 2 large numbers in C. Dynamically allocated array length changes after array passes through function


I'm writing a program to add two extremely large numbers using char arrays. I dynamically allocated the sum array to (the length of longer number + 1) to take into account cases like 99 + 1, where the sum has 1 more digit than the longer digit of the 2 numbers in the input. However, when I pass the sum array into the add function, the length of this dynamically allocated array somehow becomes just the length of longer number though I initialized it to (the length of longer number + 1). I really can't figure out why my code is acting this way. Help will be greatly appreciated. Thank you!

Here's my code: (my code uses a special I/O library provided by my school instead of printf and scanf).

int main()
{
    char* no1 = cs1010_read_word();
    char* no2 = cs1010_read_word();
    long length1 = strlen(no1);
    long length2 = strlen(no2);
 
    //Always keep no1 the shorter no
    if (length1 > length2) {
        long array_length = length1 + 2;
        char* sum = (char *)calloc((size_t) (array_length), sizeof(char));
        add(no2, no1, length2, length1, sum);
        cs1010_println_string(sum);
        free(sum);
    }
    else{
        long array_length = length2 + 2;
        char* sum = (char *)calloc((size_t) (array_length), sizeof(char));
        assert(strlen(sum) == (length2 + 1));
        add(no1, no2, length1, length2, sum);
        cs1010_println_string(sum);
        free(sum);
    }  
    assert(strlen(sum) == (length2 + 1));
        add(no1, no2, length1, length2, sum);
        cs1010_println_string(sum);
        free(sum);
    }
 
    //Free inputs
    free(no2);
    free(no1);
}
 
void reverse(char* str, long length)
{
    for (long i = 0; i < (length / 2); i += 1) {
        char tmp = str[i];
        str[i] = str[length - 1 - i];
        str[length - 1 - i] = tmp;
    }
}
 
void add(char* no1, char* no2, long length1, long length2, char* sum)
{
    long diff = length2 - length1;
    long carry = 0;
    long count = 0;
   
 
for (long i = (length1 - 1); i >= 0; i -= 1) {
        long addition = ((no1[i] - '0') + (no2[i + diff] - '0') + carry);
        sum[count] = ((addition % 10) + '0');
        carry = addition / 10;
        count += 1;
    }
 
    //Add remaining digits of no2
    for (long i = (diff - 1); i >= 0; i -= 1) {
        long addition = ((no2[i] - '0') + carry);
        sum[count] = ((addition % 10) + '0');
        carry = addition / 10;
        count += 1;
    }
 
    assert(strlen(sum) == length2);
    //Add remaining carry
    if (carry > 0) {
        //length2 += 1;
        sum[count += 1] = (carry + '0');
        reverse(sum, (length2));
    }
    else {
        reverse(sum, (length2));
    }
}



Solution

  • Your program has a problem on this line:

    sum[count += 1] = (carry + '0');
    

    I think you meant to use a post-increment for count like this:-

    sum[count++] = (carry + '0');
    

    Otherwise, you will attempt to write into what should have been the terminating zero of the sum char array.

    If you do that, then you will have to supply count to your reverse function, or it will be off-by-one.

    So instead of:-

    reverse(sum, (length2));
    

    You would need:-

    reverse(sum, (count));
    

    There are a few other problems with the code snippet above seemingly created by partially duplicating the else clause in main(..), which I presume is a symptom of your attempts to paste a minimal example into this site.