Question

After I thought that I've understood how they work, I tried this:

NSString *str1 = [NSString stringWithCString:"one"];
NSString *str2 = [NSString stringWithCString:"two"];
NSLog(@"str1: %x, %@", &str1, str1); //bfffd3cc, one
NSLog(@"str2: %x, %@", &str2, str2); //bfffd3c8, two

str1 = str2;
NSLog(@"str1: %x, %@", &str1, str1); //bfffd3cc, two

The value of an pointer (like str1, str2) is a memory address. When you go to that address, you reach the "area" in memory where the object is stored.

But: When I assign str2 to str1, str1 should have as an value the memory address of the same object that's referenced by str2, right? The strange thing here is, that the value of the pointer remains the same (bfffd3cc memory address), where the thing behind that address changes. that's actually completely unlogical to me ;) because I think that the memory address IS the object (or the home of the object in the memory brick, what ever). So I expected this:

NSString *str1 = [NSString stringWithCString:"one"];
NSString *str2 = [NSString stringWithCString:"two"];
NSLog(@"str1: %x, %@", &str1, str1); //bfffd3cc, one
NSLog(@"str2: %x, %@", &str2, str2); //bfffd3c8, two

str1 = str2;
NSLog(@"str1: %x, %@", &str1, str1); //bfffd3c8, two

Otherwise, I still didn't get the point. The relation between the value of the "pointer variable" and the "real value", lets say the object that's sitting behind that memory address.

Was it helpful?

Solution

Remember that a pointer variable is a variable itself, so it has an address. So &str1 results in the address of the pointer variable, and str1 is an expression that results in whatever the pointer variable is holding - the address of the object it's pointing to.

Assume that:

  • the object holding the NSString "one" is at address 0x00000100
  • the object holding the NSString "two" is at address 0x00000200

Then your pointers might look something like this:

At initialization:

str1
0xbfffd3c8  +---------------+
            |               |
            |  0x00000100   |
            |    ("one")    |
            +---------------+

str2
0xbfffd3cc  +---------------+
            |               |
            |  0x00000200   |
            |    ("two")    |
            +---------------+

=======================================

After the str1 = str2; assignment:

str1
0xbfffd3c8  +---------------+
            |               |
            |  0x00000200   |
            |    ("two")    |
            +---------------+

str2
0xbfffd3cc  +---------------+
            |               |
            |  0x00000200   |
            |    ("two")    |
            +---------------+

OTHER TIPS

you are printing the reference of your pointer, which is the address of the pointer, not the value of the pointer.

&str1 takes the address of the pointer.

Ok, remember how we said that all things "live" at some address in memory? And that a pointer is just the number, a number that is the address?

Well pointers are things too, and as such they have addresses.

When you print out &str1, you're printing out the memory occupied by the pointer. When you print out str1, you're printing out the value of the pointer, which is the memory address it points to.

When you print out *str1 you're dereferencing the pointer, and printing that prints the value pointed to.


Incidentally, good work: I've read your last two questions, and you're getting it, and to your credit writing code to prove or disprove that your understanding is correct. This is exactly what you should be doing, and you're on the right track.

Part of the problem you're having is that strings are funny things, in that a string really an array of (const) characters, and functions like NSLog are written to do the usual thing with a pointer to char, which is to print the string. Given a pointer to string, it's really looping: dereferencing the pointer, printing the pointed-to character, adding one to the pointer, printing the next character, until the character pointed to is a special character with the value 0, at which point it has found the end of the string and stops printing out characters.

You might find all this easier to understand if you use something like ints and pointers to ints.

Pointers are, in fact, integers with a dedicated arithmetic (IIRC, it is guaranteed that sizeof(int) == sizeof(void*))

If you reference pointers, you'll get the address where it is stored; if the variable is automatic, then you'll get the address in the stack where the pointer is stored: that's why you get those results.

Assignment behave like assignment between integers; in fact:

#include <stdio.h>

int main() {
        char *str1 = "Ciao";
        char *str2 = "Mondo";
        printf("%x\n", str1);
        printf("%x\n", str2);
        str1 = str2;
        printf("%x\n", str1);
}

prints:

:~$ ./a.out
80484f8
80484fd
80484fd

str1 is a pointer to a NSString value.

&str1 means: the address of the str1 variable. This is a double indirection.

I guess that you want the address of the value, i.e., str1 itself, not &str1.

Let's assume that the NSString object value containing @"one" is located at address 0x12345678 and @"two" is at 0x1234ABC0.

Initially the value of str1 is 0x12345678 and the value of str2 is 0x1234ABC0. These two values are stored in memory respectively at addresses 0xbfffd3cc and 0xbfffd3c8. These are the addresses of str1 and str2 variables, i.e., values of &str1 and &str2.

When you write str1 = str2, the assignment changes value of str1 to be the same as value of str2, i.e., value of str1 is then 0x1234ABC0. This is the address of the @"two" object. But address of str1 variable (0xbfffd3cc) is not changed.

Objects in Objective-C are worked on using pointers. So in order to handle your NSString object, you have to take a pointer to it. Which is what str1 is, a pointer to an NSString object.

If you want to send a message to your NSString, you can use the syntax [str1 doSomething].

If you want to print your string, you have to pass the pointer to NSLog AND tell NSLog that the pointer points to an NSString, which is done by the formatting rule "%@".

Now, if you just want to print the address pointed to by str1, you still have to pass the pointer str1 BUT you must tell NSLog that you are printing it as an hexadecimal value using the formatting rule "%x".

Something like that should print what you want:

// First print str1 as an hexadecimal value
// Then print the content of the NSString object str1 points to
NSLog(@"str1: %x, %@", str1, str1);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top