0

Although I know the main difference between Deep Copy and Shallow Copy but what I want to ask here is something practical.

I have

NSArray *firstArray = [NSArray arrayWithObjects:@"first", @"second",@"third",  nil];
NSArray *secondArray    = firstArray;
secondArray             = nil;

NSLog(@"First Array : %@",firstArray);
NSLog(@"Secon Array : %@",secondArray);

Both the firstArray and secondArray has the same reference as seen by putting break point.

Now my question is this, if both have same REFERENCE then why the firstArray does not change if the secondArray is changed.

I am really confused here... Can any one please make me clear.

Thanks in anticipation.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • [Difference Between Shallow Copy & Deep Copy](http://learningwithdeepak.blogspot.in/2012/11/difference-between-shallow-copy-deep.html) – Grijesh Chauhan Dec 17 '13 at 06:04
  • 3
    `secondArray` is a pointer to the `NSArray`... setting it to `nil` just means the data can't be accessed through the `secondArray` variable any more, it's not destroying the data or stopping `firstArray` from pointing at it. deep/shallow-copying isn't an sisue here - no copying is done when you have multiple raw pointers to the same data. It's like having two ownership certificates for the same dog - ripping one up doesn't let the pound destroy the dog. – Tony Delroy Dec 17 '13 at 06:08
  • @TonyD : Sorry, I was thinking that it is basic OOP Concept. – user3085885 Dec 17 '13 at 06:08
  • @TonyD : But the ownership Id say the Reference is the same. Means both `firstArray` and `secondArray` have the same reference, then destroying that one's memory location will not mean to destroy the other one's too? because it also has the same memory reference? What you say? – user3085885 Dec 17 '13 at 06:11
  • @user3085885 No. There are no references in this code whatsoever. There are only pointers, and pointers behave differently. Pointers are copied on assignment (as every other type of variable). If you do `int x = 42; int *p = &x; int *q = p; p = NULL;`, do you expect `q` to be null also? And what would happen to `x` itself? –  Dec 17 '13 at 06:12
  • @user3085885: it does get a bit confusing. Normally, if you have some data with pointers to further data, then you talk of shallow-copying only the top-level data or deep-copying both sets of data. Here, you have *pointers* to data which may or may not have pointers to further data, but you're never copying the data to see whether it makes a shallow or deep copy, you're just having an extra record of where the top-level data is. – Tony Delroy Dec 17 '13 at 06:12
  • NODE: this question is NOT really about shallow vs deep copy, and shouldn't have been closed as a duplicate of such a question. It IS really about pointer semantics: **whether setting one pointer to an object to nil affects the object and other pointers to it.**. – Tony Delroy Dec 18 '13 at 07:05

1 Answers1

3

I need to use ASCII art to explain this better...

firstArray
           \
            \
             NSArray - the actual data
            /
           /
secondArray

firstArray and secondArray are just pointers, holding the same numerical (virtual) memory address where the NSArray data is stored. If one of the pointers is set to point to nil, or to some other data for that matter, it won't trigger any change in the NSArray nor the other pointer.

Note especially that while firstArray and secondArray both held the same value initially, they are distinct variables at different memory addresses. You can see that if you print:

NSLog(@"First Array : %@",&firstArray);
NSLog(@"Secon Array : %@",&secondArray);

I think you were mistaking the address they pointed to (the NSArray data's address) for their address, and then concluding they were different names for the same variable. They're not! Each has different memory.

You might want to read up on pointers: What does "dereferencing" a pointer mean?

pointers and references

A pointer variable is much like an integer variable - it takes a few bytes of memory (regardless of the size of the objects at which it may be pointed) and stores a number. That number can be used to record the (virtual) memory address (how many bytes from the 0 origin of (virtual) memory) at which a particular object of the pointed-to type may be found. So, it's a bit like having a piece of paper on which we can write the address of a house. Now, the pointer is NOT the house (data-object), and you can erase the original address and write the address of some other house anytime you like, and you can use that address to find the house. This is what happened in this question... you effectively had two "pieces of paper" on which you'd "written" the address of your "house", then erased one of them, and expected a dramatic affect such as the other piece of paper being erased and/or the house/object being destroyed. Pointers don't work like that.

Some languages have a distinct mechanism - which has been called "references", "aliases", "links" and many other things in various languages' terminology - that works like an additional name or alias for an object. Anything you "do" to one of these things is transparently done to that object instead. Returning to our house analogy: this is like having different names for your house - instead of using the street address, you may call it "home", or "my castle", and if you give the instruction "burn home" your house will really burn. With a pointer to your home - saying "burn pointer-to-home" just burns the piece of paper unless you go to a little extra effort to "dereference" the pointer and operate on the house.

When they need to be passed around the program at run-time, they reference/aliases/things... are typically implemented like pointers - effectively variables that store the address of the data object. But, regardless of whether they've been passed around at run-time or only existed transiently in the compiler's internal records, they operate as described above.

So, to people from a background where "reference" is the technical term used to describe these reference/alias/whatever things, it's "wrong" to hear people say pointers are references... our reaction is "no they're not - you'll burn the paper instead of the house if you think like that". But, there are whole communities of programmers for whom "reference" is another term for "pointer", and these other things might be known as "aliases" or "links" or "pseudonyms" or goodness knows what, or they might just not exist in that language/community (e.g. for C programmers).

All our discussion in comments is just about this potential confusion.

The important this is that you understand that operating on a pointer affects the numeric address in memory that pointer stores, and not the pointed-to object unless you dereference that pointer, and not other pointers to that object (unless they're all "smart pointers" with some deliberately orchestrated synchronisation).

I suggest you read the above until you can't get any more out of it, then re-read What does "dereferencing" a pointer mean? then reread this etc. until you're happy you've grasped it all.

Your current understanding

In comments below, you say:

Up to my understanding, Pointer is a variable that can contain a memory address in it and memory address is always takes as in sense of reference to a value.

The memory address in the pointer can reference/point-at a legitimate object/value, or it may be uninitialised or garbage, just as an integer variable may have a useful number in it or be uninitialised (not yet set), or hold some left-over value after earlier processing that you're no longer interested in.

Let me clear my point here, A Pointer has a memory address , at that memory address there will be some value.

That's ambiguous but correct however you mean it. The ambiguity: the pointer has a memory address in the sense of the memory where the pointer itself is stored. In that sense, every variable has a memory address. But, pointers also have a memory address in the sense of the memory address of the pointed-to data. (This is explained in my other answer linked above.)

So if some one has to get that value, there must be a reference to reach there and that reference is the property of that Point that is containing it.

Well, I think by value you mean the poined-to value: you must have a "memory address" to reach there (whether you want to call that address a reference is discussed above), and that address is stored in the pointer, so you could consider it a "property" of the pointer if you use "property" in the sense used by some languages. So yes! :-) I think your understanding's probably correct, but your terminology is still a little imprecise and ambiguous.

Community
  • 1
  • 1
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • Does it mean, that at memory level, there will be three allocations, `firstArray`, `secondArray` and `NSArray` (where data is stored). And both `firstArray` and `secondArray` are holding the same reference of `NSArray` from the memory? Am I right here? – user3085885 Dec 17 '13 at 06:21
  • @user3085885 Yes, that's effectively right. (I say *"effectively"* only because internally the NSArray data may use multiple allocated areas - I've no idea as I'm a C++ programmer not Objective-C - but it's not relevant to the two pointers.) You may want to see http://stackoverflow.com/questions/647260/deep-copying-an-nsarray – Tony Delroy Dec 17 '13 at 06:23
  • @user3085885 Again, there are no "references" here. They are pointers, and **not** references. Don't call them references, because your confusion arises exactly out of you mixing up references and pointers. –  Dec 17 '13 at 07:16
  • @H2CO3: I think "reference" has no special meaning in Objective-C anyway, and is used interchangeably with pointer, same as in C...? If so, it's only confusing/wrong to us C++ programmers. ;-) – Tony Delroy Dec 17 '13 at 07:20
  • @TonyD I'm not a C++ programmer, but one thing is sure: a reference isn't (and never was) interchangeable with a pointer. C has no references. Whoever talks about "references in C" is automagically, inherently **wrong.** C only has **pointers,** which - as it can be seen *very clearly* e. g. by considering this very case - behave absolutely, totally, utterly differently (I knowly, too manyly adverbly...) –  Dec 17 '13 at 07:49
  • @H2CO3: the Computer Science community - including C programmers - has talked of "pass by reference" for half a century, and the C Standard itself says things like: "A pointer type may be derived from a function type, an object type, or an incomplete type, called the referenced type. A pointer type describes an object whose value provides a reference to an entity of the referenced type. A pointer type derived from the referenced type T is sometimes called ‘‘pointer to T’’." etc.. Less formally, associated words like "reference" have been used for pointers - why not? - they weren't ambiguous. – Tony Delroy Dec 17 '13 at 08:08
  • @TonyD This: "A pointer type describes an object whose value provides a reference to an entity of the referenced type" doesn't mean that a pointer is a reference. As to the question of ambiguity: if there's no ambiguity, then what did confuse OP? Surely if we considered pointers as references, then OP would be right and writing any of them would cause the other one to be changed too. But that's not the case -- exactly because the objects in question are pointers, and not references. –  Dec 17 '13 at 08:11
  • @H2CO3: you really can't see how your argument is circular? The OP is confused about pointer semantics. It's *because* you have a firm preconception of references and pointers as being different, and with that understanding see the OP expected C++-like reference semantics from pointers, and called them references to boot, that you see saying "they're not references they're pointers" as a necessary, useful and meaningful distinction. I'm saying it may not be to the OP, as operating in a language with only pointers, and documentation which sometimes calls them references, the only thing... – Tony Delroy Dec 17 '13 at 08:54
  • ...that matters is understanding pointer semantics. That need not be contrasted with anything in particular. Hundreds of thousands of people understood pointers in C without needing a distinct reference ability to contrast it with. – Tony Delroy Dec 17 '13 at 08:54
  • This is silly argument. In a computer science sense, C pointers are clearly a sort of reference, just as `T*`, `T&` and `T&&` are all types of references with slightly different semantics in C++. The fact that only the latter two are called "references" by C++ programmers doesn't change that. Likewise, dummy arguments in Fortran are clearly a kind of reference, even though the convention is to call them by a different name. – Tristan Brindle Dec 17 '13 at 09:15
  • @All : Up to my understanding, Pointer is a variable that can contain a memory address in it and memory address is always takes as in sense of reference to a value. Let me clear my point here, A `Pointer` has a `memory address` , at that memory address there will be some value. So if some one has to get that value, there must be a reference to reach there and that reference is the property of that Point that is containing it. Please make me correct if I am getting it in wrong way.Thank you. – user3085885 Dec 18 '13 at 06:42