NSArray and NSMutableArray address in memory


#1

Hi there,
I have a little confusion concerning the address in the memory for NSArray classes.
As I got from the chapter about C itself the address of the array in the memory points to the first element of this array.
So, if we write some piece of code in a way like:

int pointersArray[2] = { 1, 2 };
printf("%i, %i", pointersArray, pointersArray[0]); 

we would get the same address in the memory.
If we go back to the Obj-c book it’s written there:

Thus, I assumed that it also points to the first element of the NSArray.

But, now in the NSArray and NSMutableArray section I tried to do NSLog of items array and its first element like

NSLog(@"%p, %p", items, items[0]);

and it gives me two different addresses in the memory.

Why is that? Maybe I am missing something here… thanks!


#2
int pointersArray[2] = { 1, 2 };
printf ("%p, %i", pointersArray, pointersArray[0]);   // will print an address and an int value (1)
printf ("%p, %p", pointersArray, pointersArray + 0);  // will print same addresses
printf ("%p, %p", pointersArray, &pointersArray[0]);  // will print same addresses

The value of pointersArray is an address, but the value of pointersArray[0] is an int. (Hence the format string “%p, %i”.)

NSLog (@"%p, %p", items, items[0]);  // will print two different addresses
NSLog (@"%p, %p", items, items + 0); // should print same addresses, but I am not sure here because I don't have the latest compiler.

The value of items is an address: the address of the items object; the value of items[0] too is an address: the address of the object contained in items[0].


#3

Thanks for the answering!
it’s clear now with C, though I still don’t get it with Obj-c that much…

Gives me the error, can’t compile it: "Arithmetic on pointer to interface ‘NSMutableArray’ which is not a constant size…"
if I change it to &items I get the following:

NSLog (@"%p, %p", items, items[0]); 
NSLog (@"%p, %p", items, &items); 

2013-01-09 21:47:26.587 RandomPossessions[64619:303] 0x10010a760, 0x100001298
2013-01-09 21:47:26.597 RandomPossessions[64619:303] 0x10010a760, 0x7fff5fbff768

[quote=“ibex10”]
The value of items is an address: the address of the items object; the value of items[0] too is an address: the address of the object contained in items[0].[/quote]

So, the address of items object and the address of items[0] are two different addresses? I though that items address should point to the first element, thus items[0], no?


#4

As I had indicated, I was not quite sure with this statement:

NSLog (@"%p, %p", items, items + 0); // should print same addresses, but I am not sure here because I don't have the latest compiler.
NSLog (@"%p, %p", items, items[0]); 
NSLog (@"%p, %p", items, &items);    // Will print the address of items object and the address of the variable items.

The second statement is an interesting one: it will print the address of the items object and also the address of the variable items. The value of the variable is the address an object, the items object; but the variable too has an address, &variable.


#5

[quote=“ibex10”]
The second statement is an interesting one: it will print the address of the items object and also the address of the variable items. The value of the variable is the address an object, the items object; but the variable too has an address, &variable.[/quote]

I’m sorry, not quite sure I got the whole idea where did we get the variable items and why it’s two of them…
Anyway, is it correct that the address of items object and the address of items[0] are two different addresses? It doesn’t point to the first element after all, it points to itself?


#6

Could you please post your source file(s)? I need to see how the variable items has been declared.


#7

No problem, that’s all I have for this case:

#import <Foundation/Foundation.h>

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

	@autoreleasepool {

        NSMutableArray *items = [NSMutableArray array];
		
        [items addObject:@"One"];
        [items addObject:@"Two"];
        [items addObject:@"Three"];
        [items insertObject:@"Zero" atIndex:0];
		
		NSLog (@"%p, %p", items, items[0]);  // will print two different addresses
		NSLog (@"%p, %p", items, &items); // should print same addresses, but I am not sure here because I don't have the latest compiler.

	}
    return 0;
}

#8

Please speak up if anything is not clear with the following example:

##import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    @autoreleasepool
    {
        // Declare items as an NSMutableArray array
        NSMutableArray *items = [NSMutableArray array];
        // L-valued expressions items [0], items [1], etc. would be illegal

        // items is a variable holding the address of an NSMutableArray instance.
        // the value of items yield the address of the NSMutableArray instance.
        // items variable too has an address, given by the expression &items
        
        [items addObject:@"One"];
        [items addObject:@"Two"];
        [items addObject:@"Three"];
        [items insertObject:@"Zero" atIndex:0];
        
        // Print addresses of objects contained in the items array
        NSLog (@"%p, %p %p", [items objectAtIndex:0], [items objectAtIndex:1], [items objectAtIndex:2]);

#if 0
        // This statement will not compile
        // because items is declared as NSMutableArray *items and thus the expression items [0] would be illegal
        NSLog (@"%p, %p", items, items [0]);
#endif
        // Print the address of the items array object
        // and also the address of the variable items, holding the items array object.
        NSLog (@"%p, %p", items, &items);
        assert (items != &items);

        // Declare foos as an array of two NSMutableArray arrays
        NSMutableArray *foos [2] = {[NSMutableArray array], [NSMutableArray array]};
        // L-valued expressions foos [0], foos [1], etc. are allowed
        // foos has two array cells, each holding the address of an NSMutable array
        
        // Print the address of the first cell of the array
        NSLog (@"%p, %p", foos, foos + 0);
        NSLog (@"%p, %p", foos, &foos [0]);
        assert (foos == foos + 0);
        assert (foos == &foos [0]);
        
        // Print the addresses of the two NSMutableArray arrays
        NSLog (@"%p, %p", foos [0], foos [1]);
        assert (foos [0] != foos [1]);
        
        // Print the addresses of the two array cells holding the two NSMutableArray arrays
        NSLog (@"%p, %p", &foos [0], &foos [1]);
        assert (&foos [0] != &foos [1]);
    }
    return 0;
}

The output:

2013-01-10 21:38:27.198 titicaca[1623:403] 0x10a1c0118, 0x10a1c00b8 0x10a1c00d8
2013-01-10 21:38:27.200 titicaca[1623:403] 0x10a214430, 0x7fff69dbe8a8
2013-01-10 21:38:27.200 titicaca[1623:403] 0x7fff69dbe890, 0x7fff69dbe890
2013-01-10 21:38:27.201 titicaca[1623:403] 0x7fff69dbe890, 0x7fff69dbe890
2013-01-10 21:38:27.201 titicaca[1623:403] 0x7f83a31000d0, 0x7f83a3100000
2013-01-10 21:38:27.201 titicaca[1623:403] 0x7fff69dbe890, 0x7fff69dbe898

#9

Thanks a lot!