0

I'm acquainting myself with c-strings and pointers by using a very simple program.

This version, which passes in a string by reference, works:

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

void test(char **string) {

    *string = (char *)malloc(5);
    char *temp = "hell";
    strcpy(*string, temp);
}

int main(int argc, char *argv[]) {

    char *string = NULL;
    test(&string);
    printf("%s\n", string);
    return 0;
}

It prints "hell".

This version, which simply passes the string by value, does not work, and results in a SEGFAULT:

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

void test(char *string) {

    string = (char *)malloc(5);
    char *temp = "hell";
    strcpy(string, temp);
}

int main(int argc, char *argv[]) {

    char *string = NULL;
    test(string);
    printf("%s\n", string);
    return 0;
}

From what I know, the first version makes sense because I pass in the address of the address of the string. Thus, when I dereference this double pointer, I get the real address of the string and can reassign it with malloc.

The second version, however, I'm kind of unclear why it doesn't work. In this version I pass the address of string into the test function. I read that everything in C is passed by value but that array names are actually addresses. Doesn't this mean that I'm passing in the actual address of string into test? Shouldn't things work out the same? I'm confused, please help me out.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
nemo
  • 57
  • 4
  • 1
    For the same reason you need to pass an `int` by reference if you want to change its value. – juanchopanza Sep 28 '15 at 06:26
  • C uses [pass by value](http://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value) – M.M Sep 28 '15 at 06:48

4 Answers4

3

Remember This : In C programming to use a value,you pass "by value". To change a value you must pass "by address". So,if what you want to change is an address,then you need to pass its address to change it.otherwise you may only use it.

machine_1
  • 4,266
  • 2
  • 21
  • 42
2

When you pass an argument "by value", the value of the argument is copied into the formal argument in the function. Changing a copy (in your case string inside the test function) will of course not change the original (string in the main function).

On a side-note, C doesn't actually have "pass by reference", it only have pass by value. You emulate pass by reference by using pointers.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

In your second version, string itself is being passed by value, so you simply cannot change string itself. This is for the similar reason you cannot change the value of an int or float when it is passed by value. While an argument is being passed by value, there is a local copy created in the called function's stack.

You can always change the content of string, however.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

In C, array type is represented as a pointer to its first element. * in type means "pointer to", but outside of type means "dereference pointer". When you pass argument to function, in the body of function, you have copy of the thing, that you passed. Lets analyse your code with that in mind:

void test(char **string) {        //expect pointer to string
    *string = (char *)malloc(5);  //dereference pointer to string and allocate memory (*string is of type char*, it is a string)                      
    char *temp = "hell";          //create new string
    strcpy(*string, temp);        //copy new string to the old one
}
int main(int argc, char *argv[]) {
    char *string = NULL;     //create empty pointer (string is array, which is pointer to char), but NULL is not a valid string
    test(&string);           //pass pointer to string
    printf("%s\n", string);  //print string
    return 0;
}

**sting did not change, but its contents *string did. And in the second one:

void test(char *string) { //with this type, you could modify, what is actual string content (for example first letter), but you pass here NULL, so there is nothing you can do
    string = (char *)malloc(5); //here, you are changing only COPY of the pointer, that you passed in main
    char *temp = "hell";        //create another string
    strcpy(string, temp);       //copy new string to the one created, after this operation pointer to the string is lost
}

int main(int argc, char *argv[]) {
    char *string = NULL;  //the same
    test(string);         //pass the string, you are screwed here, values in C are passed by copying, so even if you modify the string correctly, you will not see the result
    printf("%s\n", string); //the string variable never changed from NULL, so you get the error
    return 0;
}
tkowal
  • 9,129
  • 1
  • 27
  • 51