Reputation: 69
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!
Upvotes: 0
Views: 246
Reputation: 311028
For starters this statement
str[len] = '\0';
writes beyond the allocated character array that was allocated in this declaration using the sub-expression ++len
.
char * str = (char*)malloc( (++len * sizeof(char)) );
So already the program has undefined behavior.
Also due to the condition of the while loop
while (i > 0);
you never set the element of the array str[0]
.
As the function parameter has the signed integer type int
then the user can pass a negative number. You should process such a situation correctly.
The function can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
#include <stdlib.h>
size_t len_num( int x )
{
const int Base = 10;
size_t n = 0;
do
{
++n;
} while ( x /= Base );
return n;
}
char * solution( int x )
{
const int Base = 10;
size_t len = len_num( x );
int sign = x < 0;
if ( sign ) ++len;
char *s = (char * )malloc( len + 1 );
if ( s )
{
s[len] = '\0';
do
{
s[--len] = ( sign ? -( x % Base ) : ( x % Base ) ) + '0';
} while ( x /= Base );
if ( sign ) s[--len] = '-';
}
return s;
}
int main(void)
{
int x = 12345;
char *s = solution( x );
if ( s ) puts( s );
free( s );
x = -12345;
s = solution( x );
if ( s ) puts( s );
free( s );
return 0;
}
The program output is
12345
-12345
Upvotes: 1
Reputation: 224082
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);
Upvotes: 2