Search code examples
cdynamic-memory-allocationc-stringsfunction-definition

C string is empty after assignment


I was trying to solve a coding problem to covert an integer to a string using C. e.g. if there is an integer 321, then the function should return a string "321". My character assignment seems to be successful based on the output during the assignment. However, once the assignment is complete, my string is completely empty. Not sure why this would be happening. I am guessing it has something to do with the null terminating character?

char * solution(int X) {
   
    printf("x is %d\n", X);
    
     int len = len_num (X);  //Returns correct length as tested.
     printf("Length is %d\n", len);
     
     char * str = (char*)malloc( (++len * sizeof(char)) ); //one extra space for '\0'

     str[len] = '\0';   //Assigning the last character as null terminating character '\0'
     int i = len - 1 ;
     do  
     {   
         int n = X%10;
         str[i] = '0' + n;
         printf("str[%i]:%c, n:%d.\n", i, str[i], n);
         X = X / 10;
         i--;
     }while (i > 0);
   
     printf("\nstr:%s.\n", str);
     return str;
}
Output:
x is 942
Length is 3
str[1]:2, n:2.   <---- All assignments are successful 
str[2]:4, n:4.
str[3]:9, n:9.

str:.            <----This shouldn't be empty!

Solution

  • You have some off-by-one errors.

    The first is here:

     char * str = (char*)malloc( (++len * sizeof(char)) ); //one extra space for '\0'
    
     str[len] = '\0';   //Assigning the last character as null terminating character '\0'
    

    You allocate enough space, but because len was incremented str[len] is off the end of allocated memory, and writing to caused undefined behavior. You instead want:

    char * str = malloc( len + 1 );
    

    Noting that you shouldn't cast the return value of malloc and that sizeof(char) is defined to be 1.

    Related to this, at the bottom of the loop you decrement i and then check if it is greater than 0. This means you never write to element 0 of the array. You want:

     do  
     {   
         ...
     }while (i >= 0);