Below is a C program I have written to print different combination of characters in a string.
This is not an efficient way as this algorithm creates a lot of extra strings. However my question is NOT about how to solve this problem more efficiently.
The program works(inefficiently though) and prints the different combination of the characters of string(correctly). But when I try to free
the extra strings that is getting created I run into issue. The free
that is causing issue is at the end of the recur_printc
function (it is commented).
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 3
void recur_printc(char *, int, char *);
int main()
{
char str[] = "abc";
char *print_arr = malloc(N * sizeof(char));
//Call recur_print
recur_printc(print_arr, 0, str);
free(print_arr);
return 0;
}
void recur_printc( char *print_arr, int index, char *remaining)
{
int i, j, rem_len, index_4_next;
//base case, only last character remaining
if(strlen(remaining) == 1)
{
print_arr[index] = remaining[0];
//Print the print_arr
for(i=0; i<N; i++)
{
printf("%c",print_arr[i]);
}
printf("\n");
return;
}
//If more than one character remaining
else
{
rem_len = strlen(remaining);
for(i=0; i<rem_len; i++)
{
//Add one character to print_arr
print_arr[index] = remaining[i];
//now create the string with remaining characters
char *remaining_for_next = malloc((rem_len-1) * sizeof(char));
index_4_next = 0;
for(j=0; j<rem_len; j++)
{
if(j != i)
{
remaining_for_next[index_4_next] = remaining[j];
index_4_next++;
}
}
//call recur_print
recur_printc(print_arr, index+1, remaining_for_next);
//Free the remainin_for_next
/*------This is causing issues----*/
//free(remaining_for_next);
remaining_for_next = NULL;
}
}
}
When I ran this program in gdb
I noticed that when i=1
for the first instance of recur_print
, a strange thing happens with the malloc
.
When this line is executed :
char *remaining_for_next = malloc((rem_len-1) * sizeof(char));
Although rem_len-1
equals to 2
, malloc allocates 3
bytes, and then the whole algorithm fails because the somewhere in the code strlen
of this string is used (which will be 3 instead of 2). Not sure what is happening.(This does not happen when I comment out the free()
line.)
Below is gdb output :
42 char *remaining_for_next = malloc((rem_len-1) * sizeof(char));
(gdb) print remaining_for_next
$3 = 0x0
(gdb) n
43 index_4_next = 0;
(gdb) print remaining_for_next
$4 = 0x602030 "@ `"
(gdb) print rem_len-1
$5 = 2
(gdb) q
Sorry for the long post. Once again, my question is NOT about how to print the combination in a different(and better) way. My question is why the above code fails when I try to free the remaining_for_next
string (maybe why malloc is getting affected).
Every time you are creating your string, you are not appending a null terminator, which causes the error.
So change this:
to this:
Output:
Tip: It's almost always a must to null terminate your strings, do not forget it!
Important edit:
As alk noticed, you need to change this:
to this:
in order to make space for the null terminator.
Nice question, +1.