JosiP
JosiP

Reputation: 3079

C return value using argument to function

I'm trying to run function which will return two strings by passing a pointer to them:

#include <stdio.h>

void gen_str(char *str1, char *str2){
   char *s1 = "abcd";
   char *s2 = "defg";
   str1= strdup(s1);
   str2= strdup(s2);
   printf("\n\r str1 %s str2 %s\n\r", str1, str2);
}


int main(void){
   char *s1, *s2;
   gen_str(s1, s2);
   printf("\n\r s1 %s s2 %s\n\r", s1, s2);
   return 0;
}

where output is:

str1 abcd str2 defg


 s1 8, s2 8,

Can someone tell me, what I'm doing wrong? I thought that strdup() will alloc memory for my new strings, and return pointers filled with strings. But actual behavior is different. So I'm asking for help.

Upvotes: 0

Views: 6581

Answers (4)

David Schwartz
David Schwartz

Reputation: 182847

You can's use the value of a variable before you've initialized it!

   char *s1, *s2;
   gen_str(s1, s2);

The first line doesn't assign any particular values to s1 and s2. But then you pass them to gen_str. To have another function fill in the value of a variable, pass a pointer to that variable to the function, not its value.

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

void gen_str(char **str1, char **str2){
   const char *s1 = "abcd";
   const char *s2 = "defg";
   *str1 = strdup(s1);
   *str2 = strdup(s2);
   printf("\n str1 %s str2 %s\n", *str1, *str2);
}


int main(void){
   char *s1, *s2;
   gen_str(&s1, &s2);
   printf("\n s1 %s s2 %s\n", s1, s2);
   free(s1);
   free(s2);
   return 0;
}

Upvotes: 0

Seth Carnegie
Seth Carnegie

Reputation: 75150

You're only changing the pointer inside the function. To change it outside the function, you'll need to pass the function the address of the two strings, like this:

#include <stdio.h>

void gen_str(char **str1, char **str2){
   char *s1 = "abcd";
   char *s2 = "defg";
   *str1= strdup(s1);
   *str2= strdup(s2);
   printf("\n\r str1 %s str2 %s\n\r", *str1, *str2);
}


int main(void){
   char *s1, *s2;
   gen_str(&s1, &s2);
   printf("\n\r s1 %s s2 %s\n\r", s1, s2);
   return 0;
}

Upvotes: 0

Kerrek SB
Kerrek SB

Reputation: 477512

You got your pointers confused. The basic type for a C string is already char*, and now you want a pointer to that, i.e. a char**:

void fill_me(char ** ps)
{
  const char * t = "hello";
  *ps = strdup(t);
}

/* elsewhere */
char * s;
fill_me(&s);

Moral: If you want a function to modify an argument passed by the caller, the caller needs to take the address-of (&) something at some point.

Upvotes: 5

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272687

You need your function to modify the pointers s1 and s2, so you need to pass their addresses, so that the function can modify the originals, not a copy.

void gen_str(char **str1, char **str2){
   char *s1 = "abcd";
   char *s2 = "defg";
   *str1= strdup(s1);
   *str2= strdup(s2);
   printf("\n\r str1 %s str2 %s\n\r", *str1, *str2);
}


int main(void){
   char *s1, *s2;
   gen_str(&s1, &s2);
   printf("\n\r s1 %s s2 %s\n\r", s1, s2);
   return 0;
}

Note also that you need to free these strings at some point, otherwise you have a memory leak.

Upvotes: 6

Related Questions