0

it is my first time posting here :) I've tried searching here, but failed to find an answer to my specific question. I am quite new to C, mainly used C# until now, so the whole pointers idea is not my piece of cake ..

I tried to create a function which turns an integer to a string, and I succeded until the part of returning the value .. I do not understand why inside the end of the function, the string is being printed correctly, but it is not the case at the main function. It would be appreciated if someone could take a look at the code and explain to me why it does not work (why it prints nothing at the main function).

Main Function:

int main()
{
    printf("%s", int_to_string(4058));
    return 0;
};

Int to String Function:

char* int_to_string(int n)
    {
    int len = int_length(n);
    char str[len];
    int count = 1;
    while (n != 0)
    {
        char c = (n % 10) + '0';
        str[len - count] = c;
        count++;
        n /= 10;
    }
    char* s = str;
    printf(s); // Works perfectly, prints the number as a string of characters
    return s;
};

Sub-Func - Int Length Function:

int int_length(int s)
{
    int count = 0;
    while(s != 0)
    {
        count++;
        s /= 10;
    }
    return count;
};

Your help will be truly appreciated!

M. Kasuro
  • 11
  • 5

2 Answers2

1

You're returning the address of a local variable, namely str. Once the function exits, that address is no longer valid. Attempting to dereference that address invokes undefined behavior.

You should change your function to declare str as static so that its lifetime exists after the function exits. You'll need to make the array a fixed size in this case, so make it at least 12 bytes, which should be big enough to hold the string representation of a 32 bit int.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • @M.Raz Glad I could help. Feel free to [accept this answer](https://stackoverflow.com/help/accepted-answer) if you found it useful. – dbush Jul 21 '17 at 18:02
1

The main issue with your program is that you are returning a reference to an auto character array. This means that the array is dead after the function returns and hence is not accessible in the main function. You can read more about scopes of variables to understand this better.

As it stands you have two ways of fixing this issue.

  1. Use the heap - You can allocate a character array on the heap using the malloc function. Any memory allocated on the heap is guaranteed to stay in scope till the program exits or until it is explicitly freed. So you can change your array declaration to -

    char *str = malloc(len+1); //As suggested by BLUEPIXY size needs to be len+1 to accomodate the \0
    

    with this you have to also remember to free the allocated memory after it is done using. So in main you will have to change to

    char *str = int_to_string(5098);
    printf("%s", str);
    free(str);
    
  2. Allocate the memory in the caller - If you don't want to get into the mess of allocating memory in the heap and freeing it later. You can allocate the memory in the caller and pass it to your function as

    char str[len+1]; // Same reasoning as before for len+1
    printf("%s", int_to_string(5098, str));
    

    and your function will change to

    char* int_to_string(int n, char *str){
        // No need to declare str now. Start using as before
        ...
        return str;
    }
    

    In this case you don't need to worry about freeing the memory since it will automatically go out of scope when main returns.

Also unrelated to your question there is a fatal bug with your code. You are not null terminating your string. This will be lead to Undefined Behavior when passed to printf with the %s format string modifier.

So a simple fix would be

str[count] = '\0'; 

just at the end of the function. I hope this helps.

Ajay Brahmakshatriya
  • 8,993
  • 3
  • 26
  • 49
  • @BLUEPIXY I think this is the best solution as making variable static will cause problem letter and this answer is best suitable for real world scenario. Don't You think so? – Omkar Mozar Jul 21 '17 at 18:15
  • @BLUEPIXY Thanks, I have updated the example to make space to accommodate the null terminator. As for being able to use it like `printf("%s", int_to_string(4058));`, I am not sure if that is really important. Clearly OP wants to do more than just print the string. Else they could have just used `%d`. Maybe that's just what I think, but this seems more cleaner to me that using static arrays. – Ajay Brahmakshatriya Jul 21 '17 at 18:15
  • Your solution, sir, is very detailed and beautiful. I find it helpful for my question, and it also helped me with another problem I had. Thank you! – M. Kasuro Jul 21 '17 at 19:25