tags:

views:

87

answers:

3

gcc 4.4.4 c89

#define SIZE 5
    char *names[SIZE] = {"peter", "lisa", "simon", "sarah", "julie"};
    char *search_names[SIZE] = {0};
    size_t i = 0;

    for(i = 0; i < SIZE; i++ ) {
        search_names[i] = names[i]++;
    }

    for(i = 0; i < SIZE; i++) {
        printf("name to search for [ %s ]\n", search_names[i]);
    }

I am confused about this line search_names[i] = names[i]++; Which is a array of pointers to char*. Just my experimenting I was thinking that it should be &names[i]++. Because I want to get the pointer at that location. So having the & would get me the address of where the pointer is pointing.

I guess I could increment as well like this: (names[i]) + i;

Just confused about that line.

+2  A: 

names[] is defined as an array of pointers to chars. Therefore, names[i] is a pointer to the ith string contained in names. search_names[] is an array of pointers to char as well and therefore, search_names[i] is a pointer as well. Therefore there is no need to apply the address operator to names[i] to get search_names[i] to point to the same string as names[i] does. Hope this clarifies things for you.

ennuikiller
+3  A: 

names[i] is a pointer, having type char*. &names[i] is a pointer to names[i], and hence has type char**. A picture of some memory:

names                    for each i, this is where names[i] *points*
|__________________          0     1    2     3     4
|                  |         |     |    |     |     |
|                  |         v     v    v     v     v
[0 ][1 ][2 ][3 ][4 ]  <gap>  peter0lisa0simon0sarah0julie0
        ^
        |_This is where &names[2] points, i.e. this is where names[2] *is*

name is an array of 5 pointers, and I've depicted each pointer with square brackets and its index. Plus a space, because pointers are 4 byte on my machine. This is the situation just after names has been initialised. The separate chunk of memory on the right is a sequence of bytes, with each 0 indicating a 0 / NUL byte, not the character 0. It's the responsibility of the implementation (compiler, linker and loader working together) to assign memory for string literals - I have assumed that all of the string literals you've used will be clustered together, although that needn't be the case. Finally, the numbers 0 ... 4 indicate where each pointer in names is pointing to.

Since you're assigning to a char*, you need a char*. Or looking at it another way, pointers point to the same thing if (and only if) the pointers themselves have the same value. So if you want search_names[i] (which is a pointer) to point to the same thing that names[i] points to, then search_names[i] = names[i] is exactly right.

I don't know what the intent is of doing names[i]++, though. It modifies the pointer names[i]. Modifying a pointer makes it point to a different thing. In this case you'll end up with names[0] pointing to "eter", names[1] pointing to "isa", and so on.

Here's what memory looks like after you've incremented each pointer in names:

names                
|_____________           0     1    2     3     4
|             |          |     |    |     |     |
v             v          v     v    v     v     v
[0][1][2][3][4]         peter0lisa0simon0sarah0julie0

By the way, you're allowed to assign a string literal to char*, but that doesn't mean you should. It would be better to declare your arrays const char *names[SIZE]. It's undefined behaviour to modify the memory which the compiler has assigned for a string literal, and using a const char* rather than a char* helps enforce that.

Steve Jessop
Great explanation. Thanks.
robUK
+1  A: 

So you're trying to copy the array names into search_names? Do note that names and search_names are both pointers to characters. IE, names[i] is a pointer.

The expression

search_names[i] = names[i]

Assigns the value of search_names[i] to be names[i]. This is simply putting the content on the runtime stack at address &names[i] into the cell at address &search_names[i]. In this case, it's copying just a pointer. It will NOT copy the characters. It will ONLY copy the content from the cell names[i]--the pointer to the first character of a sequence of characters.

The reason why

search_names[i] = names[i]++; 

is equivalent to

search_names[i] = names[i]

in the context of search_names is because the increment operator affects the value of names[i]. It has a lower precedence AFTER the assignment operator. So the expression will increment names[i] after the assignment. Since names[i] is a pointer, the increment does some pointer arithmetic, which means it will point to address (names[i] + sizeof(char) ).

Kizaru