-3

So I am making a program to find the max possible substraction. If n is, f.e 9284, the minimum number which can be made with the digits of 9284 is 2489 and the maximum one is 9842. the function max_substraction returns 9842 - 2489 as output.

The problem is that whenever I run the program and type a number, the program crashes. I did try to debug and I was told that the function "to_digits" was excepting int * but int given which is really strange. Ain't I returning a pointer? ...

#include <stdio.h>

int valid(int);
int length(int);
int to_digits(int);
int to_num(int *, int);
void sort_digits(int *, int);
int max_substraction(int *, int);

int i,j;

int main()
{
    int num;
    scanf("%d", &num);
    if(!valid(num))
    {
        printf("Invalid!\n");
    }
    else {

        printf("%d", max_substraction(to_digits(num), length(num)));
    }
    return 0;
}

int length(int num){

    int cpy_of_num = num, len = 0;
    do {
        cpy_of_num /= 10;
        len++;
    } while(cpy_of_num != 0);

    return len;
}

int valid(int num){
    int len = length(num);
    if(len<2 || len>9){
        return 0;
    }
    return 1;
}
int to_digits(int num){
    int len = length(num), cpy_of_num = num;
    int digits[len];
    for(i=len-1; i>=0; i--){
        digits[i] = cpy_of_num % 10;
        cpy_of_num /= 10;
    }
    return *digits;
}
int to_num(int *digits, int len){
    int new_num = 0, mult = 1;
    for(i=len-1; i>=0; i--){
        new_num += digits[i]*mult;
        mult *= 10;
    }
    return new_num;
}
void sort_digits(int *digits, int len){
    for(i=1;i<len;i++){
        for(j=0;j<len-1;j++){
            if(digits[j] > digits[j+1]){
                int temp = digits[j];
                digits[j] = digits[j+1];
                digits[j+1] = temp;
            }
        }
    }
}
int max_substraction(int *digits, int len){
    sort_digits(digits, len);
    int max_num_digits[10], min_num_digits[10];
    for(i=0; i<len; i++){
        min_num_digits[i] = digits[i];
        max_num_digits[i] = digits[len-i-1];
    }
    int min_num = to_num(min_num_digits, len);
    int max_num = to_num(max_num_digits, len);

    return max_num - min_num;
}
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Caitiff
  • 47
  • 3
  • 11

2 Answers2

0

The problem is in the function call

  max_substraction(to_digits(num), length(num))

as per the signature,

int max_substraction(int *digits, int len)

the first param should be a int *, but to_digits() returns you an int!!

Then, a return statement like

  return *digits;

returns you an int value, not a pointer.

That said, even if you tried, in it's current form, digits array cannot be returned from to_digits(), as it is local to the function. You need to have static storage if you want to return the array. Now, since by definition, VLAs cannot have static storage, you may want to use memory allocator functions, like malloc() and family.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • The question is why doesn't to_digits(num) return int * – Caitiff May 11 '17 at 07:31
  • @Caitiff just elaborated on that part. – Sourav Ghosh May 11 '17 at 07:33
  • THANK YOU OMFG I FIXED IT! haha – Caitiff May 11 '17 at 07:34
  • I fixed the declaration – Caitiff May 11 '17 at 07:34
  • well that was something i could notice by myself, sry for the stupid question – Caitiff May 11 '17 at 07:36
  • 2
    Yes Caitiff, and now fix the storage problem or you would still be returning a local variable which does not exist anymore after the return...another crash. – Paul Ogilvie May 11 '17 at 07:37
  • well I wrote 80 lines of code without testing it a lot. should have looked harder for my problem instead of going here, i admit that. anyways thanks for the help – Caitiff May 11 '17 at 07:38
  • @Caitiff *it works* doesn't mean it is correct. The problem is not just with the return type. There is a problem that you are returning an array which is out of scope. – Ajay Brahmakshatriya May 11 '17 at 07:39
  • @AjayBrahmakshatriya I thought I made it clear in my answer itself...is it not? How I can clarify? Alternate wordings? – Sourav Ghosh May 11 '17 at 07:40
  • @SouravGhosh No, I am not saying anything about your answer. OP is jumping to conclusion that his problem his fixed by changing the declaration of `to_digits`. I was replying to his comment. – Ajay Brahmakshatriya May 11 '17 at 07:42
  • Um... I also fixed that as well – Caitiff May 11 '17 at 07:43
  • @AjayBrahmakshatriya I understand you're not pointing to my answer, just asking opinion about possible improvements, that's all. Thanks. :) – Sourav Ghosh May 11 '17 at 07:43
  • @Caitiff Because that is Undefined Behavior. There is no telling what would happen when UB is encountered. It might even given something similar to what you expect. But there is no point in discussing that. It might work here. In some other case it might not work (I can create a case where it will most definitely create issues). – Ajay Brahmakshatriya May 11 '17 at 07:46
  • Please do so. i would like to learn after all. give me such a case – Caitiff May 11 '17 at 07:47
  • Of course if you aren't careful, shit can happen but that doesn't mean it isnt correct – Caitiff May 11 '17 at 07:49
  • I suggest you create another case where you ask why returning a local array is not safe and I can answer that with examples. Better yet, just search on SO. The exact question must already have been asked. – Ajay Brahmakshatriya May 11 '17 at 07:51
  • @AjayBrahmakshatriya right indeed. -->Caitiff [here's one if you're interested](http://stackoverflow.com/a/37433599/2173917) – Sourav Ghosh May 11 '17 at 07:54
  • but I am passing the array. In int main I am directly passing it to max substraction as a param. I am not using its values there – Caitiff May 11 '17 at 07:59
  • the function substraction itself calls the function to sort these digits – Caitiff May 11 '17 at 08:01
0

Your function to_digits has a return type declared as int, while it in fact tries to return an int*. In it's current form the array will cease to exist when the function ends, so a different way of memory allocation is required in order to use the array outside the function to_digits.

Kroshtan
  • 637
  • 5
  • 17