user526427
user526427

Reputation: 107

C programming recursion question generating segfault

trying to convert any number to any base in a recursion with C:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* anybase(int n, int b)
{

   char * s;
   int len;

   if(n==0) {strcpy(s,""); return s;}

   s = anybase(n/b, b);

   len=strlen(s);
   s[len] = "0123456789ABCEDFGHIGKLMNOPQRSTUVWXYZ"[n%b];
   s[len+1]='\0';
printf ("%s, %d, %d\n", s, n, b);

/*   return s; */


}
int main(){

char *s;

s = anybase(900000, 18);
/*printf ("%s, %d, %d\n", anybase(90000, 18), 90000, 18);*/

}

is it the recursion having a problem? not sure why one can't return a value in the function call. what would be needed to call this recursion function and return a value instead of void.

Why is it generating seg fault each time running it? Thanks!

Upvotes: 0

Views: 99

Answers (3)

Alex Hoffmann
Alex Hoffmann

Reputation: 367

The string buffer can be created statically in the main function but must then be passed to each recursive function call such that it can be written in to.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 200
const char *selection = "0123456789ABCEDFGHIGKLMNOPQRSTUVWXYZ";

void anybase(int n, int b, char *s)
{
    if (n) {
        anybase(n / b, b, s);

        strncat(&s[strlen(s)], &selection[n % b], sizeof(char));
        printf("%s, %d, %d\n", s, n, b);
    }
}

int main()
{
    char buf[BUFFER_SIZE];
    memset(buf, 0, sizeof(char) * BUFFER_SIZE);

    anybase(900000, 18, buf);
    printf("Ouput: %s, N: %d, B: %d\n", buf, 90000, 18);
}

Upvotes: 1

hko
hko

Reputation: 676

As others mentioned the issue is s is just a pointer that points to no where. But instead of allocating memory for s inside of your anybase function a better approach is to allocate the memory in the main function. This avoids possible memory leaks when calling the function multiple times.

#include <stdio.h>
#include <string.h>

void anybase(int n, int b, char* s)
{
    int len;
    if(n==0) {strcpy(s,""); return;}

    anybase(n/b, b, s);

    len=strlen(s);
    s[len] = "0123456789ABCEDFGHIGKLMNOPQRSTUVWXYZ"[n%b];
    s[len+1]='\0';
    printf ("%s, %d, %d\n", s, n, b);
    printf("%d\n", len +1);
    return;
}
int main(){
    char s[33]; /* enough for all ints with base 2 */
    anybase(90000, 18, s);
    return 0;
}

Upvotes: 1

You were pretty much there, except you never allocated any memory for the string you're trying to produce. Here's a version which (apparently) runs correctly:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* anybase(int n, int b)
  {
  char *s;
  int len;

  if(n == 0)
    {
    s = malloc(200);
    s[0] = '\0';
    }
  else
    {
    s = anybase(n/b, b);

    len=strlen(s);
    s[len] = "0123456789ABCEDFGHIGKLMNOPQRSTUVWXYZ"[n%b];
    s[len+1]='\0';
    }

  return s;
  }

int main()
  {
  char *result;

  result = anybase(900000, 18);
  printf("%s\n", result);

  free(result);
  }

Note that since the buffer returned by anybase is allocated dynamically (using the malloc library function) it must be free'd after use.

Upvotes: 2

Related Questions