Stcok example need some clarification on using pointer twice


#1

Hello,

I would like to ask with regards to the pointer stock that was used twice. I know this was answered in another post A single pointer to multiple objects but my question why did it work? whats the mechanic behind it?

I know it has to do with allocating and initiating the pointer again, but when tracking the pointer address it is the same. So… whats happening here?

[code]#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

@autoreleasepool {
    
    NSMutableArray *stocks = [[NSMutableArray alloc] init];
    
    NSMutableDictionary *stock;
    
    stock = [NSMutableDictionary dictionary];
    [stock setObject:@"AAPL"
              forKey:@"symbol"];
    [stock setObject:[NSNumber numberWithInt:200]
              forKey:@"shares"];
    [stocks addObject:stock];
    NSLog(@"stock pointer:%p", &stock);
    
    stock = [NSMutableDictionary dictionary];
    [stock setObject:@"GOOG"
              forKey:@"symbol"];
    [stock setObject:[NSNumber numberWithInt:160]
              forKey:@"shares"];
    [stocks addObject:stock];
    NSLog(@"stock pointer:%p", &stock);
    
    [stocks writeToFile:@"<address>/stocks.plist"
             atomically:YES];
    
    NSArray *stockList = [NSArray arrayWithContentsOfFile:@"<address>/stocks.plist"];
    
    for (NSDictionary *d in stockList) {
        NSLog(@"I have %@ shares of %@", [d objectForKey:@"shares"], [d objectForKey:@"symbol"]);
    }
    
}
return 0;

}[/code]

Output

stock pointer:0x7fff5fbff8a8 stock pointer:0x7fff5fbff8a8 I have 200 shares of AAPL I have 160 shares of GOOG Program ended with exit code: 0


#2

[quote][code]
NSMutableDictionary *stock;

stock = [NSMutableDictionary dictionary];

NSLog (@“stock pointer:%p”, &stock);

stock = [NSMutableDictionary dictionary];

NSLog (@“stock pointer:%p”, &stock);
[/code][/quote]
You are printing the address of the stock variable.

You can not change the address of a variable by assigning values to it; you can only change its value.

You wanted to do this:

NSMutableDictionary *stock;
        
stock = [NSMutableDictionary dictionary];
...
NSLog (@"stock pointer:%p", stock);
        
stock = [NSMutableDictionary dictionary];
 ...
NSLog (@"stock pointer:%p", stock);

#3

Thank you ibex10.

Maybe I didn’t clarify my question. To clarify the reason I printed the address is to check if it was changing.

I have made this example code with four tests:

Test 1 string pointer testString is allocated and initiated for the first time and added to the array
result:
array[0] = "This is something"
comment: nothing special here string was added to the array.

Test 2 string pointer testString is allocated and initiated for the second time and added to the array
result:
array[0] = "This is something"
array[1] = "say what?"
comment: allocating and initiating the string added a new value to the array even though the string pointer address did not change and there was no implications on the first item in the array.

Test 3 string pointer testString is appended and added to the array
result:
array[0] = "This is something"
array[1] = "say what? this is how it is"
array[2] = "say what? this is how it is"
comment: appending the string pointer without allocating and initiating resulted in changing the values of both array[1] and array[2].

Test 4 string pointer testString is allocated and initiated for the third time using a two step process and added to the array
result:
array[0] = "This is something"
array[1] = "say what? this is how it is"
array[2] = "say what? this is how it is"
array[3] = "Back to square one"
comment: allocating and initiating the string pointer added a new value that did not have any effect on previous items even though the pointer address did not change.

having presented the above it is clear when we allocate and initiate the same string pointer for a second time something happens. what happens to the link between the first item in the array and the pointer it gained its value from?

I hope I was able to explain why I am a bit perplexed by this behavior as I would think the values in the array are associated with one pointer so I assumed (apparently wrongly so) that they should all have the value of the what ever the pointer value is at all locations in the array.

Code

[code]#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

@autoreleasepool {
    
    NSMutableString *testString;
    
    NSMutableArray *testArray = [[NSMutableArray alloc] init];
    
    // Test 1 string pointer testString is allocated and initiated for the first time
    testString = [[NSMutableString alloc] initWithString:@"This is something"];
    [testArray addObject:testString];
    NSLog(@"***test 1***");
    NSLog(@"testString pointer address: %p",&testString);
    NSLog(@"%@", testString);
    NSLog(@"testArray pointer: %p",&testArray);
    NSLog(@"%@",testArray);
    
    // Test 2 string pointer testString is allocated and initiated for the second time
    testString = [[NSMutableString alloc] initWithString:@"say what?"];
    [testArray addObject:testString];
    NSLog(@"***test 2***");
    NSLog(@"testString pointer address: %p",&testString);
    NSLog(@"%@", testString);
    NSLog(@"testArray pointer: %p",&testArray);
    NSLog(@"%@",testArray);
    
    // Test 3 string pointer testString is appended
    [testString appendString:@" this is how it is"];
    [testArray addObject:testString];
    NSLog(@"***test 3***");
    NSLog(@"testString pointer address: %p",&testString);
    NSLog(@"%@", testString);
    NSLog(@"testArray pointer: %p",&testArray);
    NSLog(@"%@",testArray);
    
    // Test 4 string pointer testString is allocated and initiated for the third time using a two step process
    testString = [NSMutableString alloc];
    testString = [testString initWithString:@"Back to square one"];
    [testArray addObject:testString];
    NSLog(@"***test 4***");
    NSLog(@"testString pointer address: %p",&testString);
    NSLog(@"%@", testString);
    NSLog(@"testArray pointer: %p",&testArray);
    NSLog(@"%@",testArray);
    
}
return 0;

}[/code]

Output

2014-02-08 21:35:58.176 Test on effect of ponters[21513:303] ***test 1*** 2014-02-08 21:35:58.178 Test on effect of ponters[21513:303] testString pointer address: 0x7fff5fbff818 2014-02-08 21:35:58.178 Test on effect of ponters[21513:303] This is something 2014-02-08 21:35:58.178 Test on effect of ponters[21513:303] testArray pointer: 0x7fff5fbff810 2014-02-08 21:35:58.179 Test on effect of ponters[21513:303] ( "This is something" ) 2014-02-08 21:35:58.179 Test on effect of ponters[21513:303] ***test 2*** 2014-02-08 21:35:58.180 Test on effect of ponters[21513:303] testString pointer address: 0x7fff5fbff818 2014-02-08 21:35:58.180 Test on effect of ponters[21513:303] say what? 2014-02-08 21:35:58.180 Test on effect of ponters[21513:303] testArray pointer: 0x7fff5fbff810 2014-02-08 21:35:58.181 Test on effect of ponters[21513:303] ( "This is something", "say what?" ) 2014-02-08 21:35:58.181 Test on effect of ponters[21513:303] ***test 3*** 2014-02-08 21:35:58.181 Test on effect of ponters[21513:303] testString pointer address: 0x7fff5fbff818 2014-02-08 21:35:58.181 Test on effect of ponters[21513:303] say what? this is how it is 2014-02-08 21:35:58.185 Test on effect of ponters[21513:303] testArray pointer: 0x7fff5fbff810 2014-02-08 21:35:58.185 Test on effect of ponters[21513:303] ( "This is something", "say what? this is how it is", "say what? this is how it is" ) 2014-02-08 21:35:58.186 Test on effect of ponters[21513:303] ***test 4*** 2014-02-08 21:35:58.186 Test on effect of ponters[21513:303] testString pointer address: 0x7fff5fbff818 2014-02-08 21:35:58.187 Test on effect of ponters[21513:303] Back to square one 2014-02-08 21:35:58.187 Test on effect of ponters[21513:303] testArray pointer: 0x7fff5fbff810 2014-02-08 21:35:58.188 Test on effect of ponters[21513:303] ( "This is something", "say what? this is how it is", "say what? this is how it is", "Back to square one" ) Program ended with exit code: 0


#4

If you are asking the question: Why are the pointers (addresses) in the array not the same?

You are changing the value of the testString pointer variable each time:

[quote][code]
NSMutableString *testString;

NSMutableArray *testArray = [[NSMutableArray alloc] init];

testString = [[NSMutableString alloc] initWithString:@“This is something”];
[testArray addObject:testString];

testString = [[NSMutableString alloc] initWithString:@“say what?”];
[testArray addObject:testString];

[/code][/quote]
The value of testString is an NSString object. When you add testString to the array, you are adding the value of the testString, not its address:

...
testString = [[NSMutableString alloc] initWithString:@"This is something"];
[testArray addObject:testString];   // Adding the value of testString to the array, not its address
...
testString = [[NSMutableString alloc] initWithString:@"say what?"];
[testArray addObject:testString];    // Adding the value of testString to the array, not its address
...

Therefore the array will contain the addresses of NSString objects, not the address of the testString variable.

Even if we introduced new variables, the values of the array would still be the same as those in the array above:

...
testString = [[NSMutableString alloc] initWithString:@"This is something"];
NSMutableString *testString_1 = testString;
[testArray addObject:testString_1];
...
testString = [[NSMutableString alloc] initWithString:@"say what?"];
NSMutableString *testString_2 = testString;
[testArray addObject:testString_2];
...

The value of a variable and the address of the variable are two independent entities. Changing the value of the variable does not change its address.


#5

[quote=“ibex10”][quote]
The value of testString is an NSString object. When you add testString to the array, you are adding the value of the testString, not its address:

[/quote][/quote]

So, are you saying that you’re essentially saving a copy of the testString into the array?


#6

Yes