Home > Software design >  changing adress of char array inside a function
changing adress of char array inside a function

Time:02-28

I'm playing with pointers and array and I found it hard to understand why this code doesn't work.

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

void change(char **test)
{
    char *test1 = malloc(sizeof(char)*17);  
    strcpy(test1, "HEAP");

    *test = test1;

}

int main()
{
    char str[15]= "hello World";    //Array of char
    change(&str);   // Passing the address of my array of char
    printf("%s", str);
}

The goal is to change the address of strto the allocated memory array inside the function change

But changing the line :

char str[15]= "hello World"; 

to this (which is read only right ?):

char *str= "hello World"; 

Also, I'm getting a warning when compiling that I don't understand either :

main.c:17:12: warning: passing argument 1 of ‘change’ from incompatible pointer type [-Wincompatible-pointer-types]
   17 |     change(&str);   // Passing the address of my array of char
      |            ^~~~
      |            |
      |            char (*)[15]
main.c:5:20: note: expected ‘char **’ but argument is of type ‘char (*)[15]’
    5 | void change(char **test)

Thank you !

CodePudding user response:

char str[15] isn't a pointer so you can't change its address. You need str to be a char*.

Example:

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

#define HEAP "HEAP"

void change(char **test)
{
    char *test1 = malloc(sizeof HEAP); // sizeof(char) is defined to be 1
    strcpy(test1, HEAP);
    *test = test1;
}

int main()
{
    char orig[] = "hello World";
    char *str = orig;          // initialize it to point at the first char in orig
    printf("before: %s\n", str);
    change(&str);
    printf("after : %s\n", str);
    free(str);                 // free what you've allocated
}

CodePudding user response:

The goal is to change the address of strto the allocated memory array inside the function change...

You cannot change the address of a variable. If a variable is a non-const pointer, you can make it point to some other memory address, provided it should be of compatible type with the type of pointer.

Before moving ahead, a couple of points for array:

  • Arrays are not pointers. They both are different.
  • In C, array names are non modifiable lvalues.

The warning message that you are getting is very clearly conveying the message - the type of argument that you are passing to change() function is not compatible with type of its parameter. The type of &str argument (passing to change()) is char (*)[15] and type of test parameter is char **.

Lets change the type of test parameter of change() function and make it compatible with the type of &str that you are passing to change() function and check what happens!
Make the following change in your program

void change(char (*test)[15])
                 ^^^^^^^^^^^

With this change when you compile your program, you will get following error:

#  gcc -Wall -Wextra prg.c
prg.c:10:11: error: array type 'char [15]' is not assignable
    *test = test1;
    ~~~~~ ^
1 error generated.

The error is occurring because test is a pointer pointing to str array and when you dereference it (i.e. *test) you get the array of type char [15] and, that means, this statement will end up attempting to assign test1 to array of type char [15] (which, in this context, is array str). Check the second point above - array names are non modifiable lvalues. Hence, this error is occurring.

So, arrays are non assignable, however, you can change the content of array in change() function using the address of str that you passing to change() function. You can do:

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

#define NUM_CHARS 15

void change(char (*test)[NUM_CHARS]) {
    strcpy (*test, "HEAP");
}

int main (void) {
    char str[NUM_CHARS]= "hello World";    //Array of char

    printf ("Before calling change(), str : %s\n", str);
    change (&str);   // Passing the address of my array of char
    printf ("After calling change(), str : %s\n", str);

    return 0;
}

Output:

# ./a.out
Before calling change(), str : hello World
After calling change(), str : HEAP

Note, that same you can achieve with passing the str to change() function, instead of passing address of str (Of course, you have to make respective changes in the change() function as well).

How to make a pointer pointing so some other memory inside a function is already shown in other post (by @Ted Lyngmo).


Follow good programming practice:

  • Always check the malloc() return.
  • Make sure to free the dynamically allocate memory once done with it.
  • Related