Changing an array with a function in C?

62,083

Solution 1

You are passing the pointer to the array by value instead of by reference. It should be:

void changeArray(char **arr){
    *arr = "bingo";
}

int main(int argc, const char* argv[]){
    char *blah = "hello";
    printf("Array is %s\n",blah);
    changeArray(&blah);
    printf("Array is %s\n",blah);
    return EXIT_SUCCESS;
}

You gave the the address of "hello" to changeArray function, but in the function you changed the value passed, not the original pointer. The change I made passes the address of the pointer, and the pointer itself is changed in the function.

Please not char *blah = "hello"; defines a pointer to a constant string, as well as *arr = "bingo";, this is both fine, but if you consider to change the string itself, you will not be able to.

EDIT:

When you pass an argument, even a pointer, to a function, you actually copies it to some place where the function read it from there (usually the stack). You don't pass the argument itself, but a copy of it. When the function modifies it (like in arr = "bingo";) it modifies the copy of the variable, not the original variable. So in order to change the variable itself, we pass the address of the variable to the function (changeArray(&blah); - the & means address of-) and in the function we modify the variable stored in the address we passed (*arr = "bingo"; - the * means the variable in the address arr).

Assuming the original blah pointer is located in the address 0x00000000 and contains the address of "hello" string which is for example 0x00000010. if you pass blah to the function, you copy it to a new variable, arr, which is located in address 0x00000020 for example

Variable    Address     content
-------------------------------
blah       00000000    00000010   (points to hello)
"hello"    00000010    "hello" (this is just an example, so don't be hard on me :) )
arr        00000020    00000010
"bingo"    00000030    "bingo" (and again...)

now if you change the content of arr you change the value in address 0x00000020, but not the value in address 0x000000000, so blah still contains 00000010.

Variable    Address     content
-------------------------------
blah       00000000    00000010   (points to hello)
"hello"    00000010    "hello" (this is just an example, so don't be hard on me :) )
arr        00000020    00000030 (points to "bingo")
"bingo"    00000030    "bingo" (and again...)

Instead what we do is copy the address of blah, which is 0x00000000, to arr and in the function we say - "the content of arr is an address, go to this address and change its content to point to "bingo" string". so now the content in address 0x00000000 (which is blah) is pointing to "bingo".

Variable    Address     content
-------------------------------
blah       00000000    00000030   (points to "bingo")
"hello"    00000010    "hello"    (this is just an example, so don't be hard on me :) )
arr        00000020    00000000   (points to `blah`)
"bingo"    00000030    "bingo"    (and again...)

Hope I didn't confuse you...

Solution 2

There are no arrays in your code. If you are actually trying to modify what your blah character pointer points to, then you need to pass a pointer to a pointer into the function. However, if you want to do this using arrays then you need to do something like:

void changeArray(char arr[]) {
  // or you can use char *arr, it's the same thing from
  // the C compiler's point of view
  strcpy(arr, "blah");
  // alternatively, you could set each element. i.e. arr[0] = 'b';
}

int main (int argc, char** argv) {
  char blah[100] = "hello"; // this is an array
  printf("Array is %s\n", blah);
  changeArray(blah);   // array decays to pointer
  printf("Array is %s\n", blah);
  return EXIT_SUCCESS;
}
Share:
62,083

Related videos on Youtube

Alex
Author by

Alex

Updated on July 09, 2022

Comments

  • Alex
    Alex almost 2 years

    I want to call a function and I want that function to change the contents of a string or array in the program to a constant.

    Psuedocode:

    some_array = "hello"
    print some_array   #prints "hello"
    changeArray(some_array)
    print some_array  #prints "bingo"
    

    I know I have to pass the pointer to that function. Here's what I wrote,

    void changeArray(char *arr){
        arr = "bingo";
    }
    
    int main(int argc, const char* argv[]){
        char *blah = "hello";
        printf("Array is %s\n",blah);
        changeArray(blah);
        printf("Array is %s\n",blah);
        return EXIT_SUCCESS;
    }
    

    How can I do this?

  • André Caron
    André Caron about 13 years
    By all means, please rephrase your answer. Arrays are always passed by reference in C. If OP wishes to change the array's content, OP should change the elements at each position. With a character array (string), OP should use strcpy() or other string function.
  • MByD
    MByD about 13 years
    @Andre - Thanks for the comment, I changed it to "the pointer to the array", but it is still true that the pointer is passed by value and not by reference. Thanks again.
  • CB Bailey
    CB Bailey about 13 years
    @AndréCaron: This is a misleading why of looking at it. Arrays are never passed into or out of functions at all in C. All functions that look like they take arrays actually take pointers and it is illegal to declare a function returning an array. All parameters, including pointers, are always passed by value into functions in C. C is a "pass by value" only language.
  • Alex
    Alex about 13 years
    Thank you very much. I don't quite understand the difference between *arr and **arr.
  • MByD
    MByD about 13 years
    @Bob - I will try to explain it in my answer.
  • MByD
    MByD about 13 years
    this is not correct, he is not copying the string but assigning his pointer to point to the new string. No allocation is needed in this code sample.
  • Jim Balter
    Jim Balter about 13 years
    @André You are incorrect; C only passes by value. An array used as an rvalue is implicitly converted to pointer to its first element. When the rvalue is passed as an argument to a function, the pointer is passed by value. All of this is explicitly and clearly stated in the C standard; I urge you to read it. And if the OP were to use strcpy that would result in undefined behavior (and crash with a memory protection violation in most implementations) because blah points to a string constant, which cannot be written to.
  • cokedude
    cokedude about 8 years
    @MByD why don't you need strcpy?
  • cokedude
    cokedude about 8 years
    @Ferruccio why don't you need a & with changeArray(blah)?
  • Ferruccio
    Ferruccio about 8 years
    @cokedude - You can't actually pass arrays as paramenters to functions in C. The arrays will "decay" into a pointer to the first element of the array, so calling changeArray(blah) is identical to changeArray(&blah[0]). Since the function is declared void changeArray(char arr[]) which is identical to changeArray(char* arr), the call matches the function signature.
  • MByD
    MByD about 8 years
    @cokedude because "bingo" is a string literal, and it is valid outside the context of the function, you can refer to it from anywhere, and so you only need a pointer to it, not a copy of it.
  • TheLogicGuy
    TheLogicGuy over 7 years
    Worth to note that the array has 100 places to ensure that there won't be an overflow of the chars to another location in the stack. previously we didn't do that because in C when you assign some string the between quotation mark to a pointer you actually point the pointer to a location the code segment and not the memory stack.
  • netskink
    netskink about 7 years
    FWIW, I always write code with an array as this void changeArray(char *arr) but on this IDE I'm working with that does not work. I had to use the notation you used. I'm wondering if its a bug with this compiler/ide set.

Related