pointer copying, no malloc

I was about to use malloc or strdup to manage this.
Finally, I tried this snippet and it works on both my linux and in the more complex code I wrote based on this approach:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void test_function(char** list, int count)
{
    printf("count=%d\n", count);

    char* list_copy[count];
    int i;
    for(i = 0; i < count; ++i) {
    	list_copy[i] = list[i];
    }
	
    printf("1- %s\n", list_copy[0]);
    list_copy[0] = "hello modified";
    printf("2- %s\n", list_copy[0]);
    printf("3- %s\n", list[0]);
}

int main() {
    char* list[] = {"hello", "hello2", NULL, "test", NULL};
    test_function(list, sizeof(list) / sizeof(char*));
    printf("4- %s\n", list[0]);
    return 0;
}


If I use char* list_copy = list to initialize list_copy, modifying list_copy[0] will obviously alter list[0].

Is this code safe?
Why modifying list_copy[0] did not modify list[0] when I initialized it element by element in for loop?

Thank you
At line 12, you are not copying "hello modified" into the memory pointed to by list_copy[0]. You are changing the value of the pointer list_copy[0] to point to a different memory address, that's storing the string literal "hello modified".

However, the value of the pointer list[0] is still pointing to the memory it was originally pointing to - the string literal "hello".
I imagined that
However, why when I initialize this way instead of lines 5 to 9:
char* list_copy = list;

In this case, line 12 will also change list[0]?

If you can link me to some text book when initializing pointer arrays that explains this difference, it would be even better.
In this case, line 12 will also change list[0]?

No. Why would it?

A pointer is just a number. It's the number of an address in memory. When we say that a pointer "points" to something, we mean that it's value is set to to address in memory where that something is stored.

Consider if you were using arrays of ints, rather than pointers:

1
2
3
4
5
6
7
8
9
10
void test_function(int* list, int count)
{
    int list_copy[count];

    for(i = 0; i < count; ++i) {
    	list_copy[i] = list[i];
    }

    list_copy[0] = 12;
}

Would list_copy[0] = 12; also change the value of list[0]? Why?

If you can link me to some text book when initializing pointer arrays that explains this difference, it would be even better.

There's nothing special or magical about arrays of pointers. They work just the same as arrays of any other kind. The value stored in each element is a pointer, but that doesn't mean they behave any differently from any other array.

If you understand arrays, and you understand pointers, there's nothing new to understand about arrays of pointers.
Last edited on
Maybe I did not explain it better, so here's the code that changes the value + its output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void test_function(char** list, int count)
{
    printf("count=%d\n", count);

    char** list_copy = list;
	
    printf("1- %s\n", list_copy[0]);
    list_copy[0] = "hello modified";
    printf("2- %s\n", list_copy[0]);
    printf("3- %s\n", list[0]);
}

int main() {
    char* list[] = {"hello", "hello2", NULL, "test", NULL};
    test_function(list, sizeof(list) / sizeof(char*));
    printf("4- %s\n", list[0]);
    return 0;
}


output:

count=5
1- hello
2- hello modified
3- hello modified
4- hello modified


So, yes, they are modified in this case, when list_new was initialized directly to list
Now that second version of the code is different from the first one you've posted, and behaves differently. Initialising list_copy the way you have done in line 5 of your second version is a different thing from what you did in lines 5 - 9 of your first version, and will result in different behaviour.

Yes, I noticed it
That was my question

I wanted to understand what happens when I initialize in the second way
I guess since list_new is a pointer to pointer, all array members will directly point to the address of list[] ?

Thank you for the help
The name of any array functions as a pointer to the first element in the array (loosely speaking). So when you do:

char** list_copy = list;

You set the number (address) that's stored in list_copy to be the address of list[0].

So from then on, list_copy is pointing to exactly the same bit of memory as list points to, and everything follows on from there.

In the first version, list and list_copy were separate arrays, and so those names were pointers to different bits of memory. You were just setting the values of the elements to be the same in each array.
Last edited on
Many thanks
Now that's very clear for me
You're welcome!
Topic archived. No new replies allowed.