rg2c+@andrew.cmu.edu (Robert Nelson Gasch) (02/10/91)
Hi, my programming background is Pascal and I've been using C for about half a year by now. Coming from Pascal, the way arrays and pointers are related is somewhat confusing. I have a question: I can define an array as int this_array[10]; this_array [0] = 1; which is straight forward and easily understandible. I can also do this, int *this_ptr; this_ptr = (int *) malloc (10 * sizeof (int)); which explicitly allocates the space for 10 integers. Now, here comes the question: What happens if I do the following? Basically I don't really understand *why* this works: int *this_ptr; this_ptr [0] = 1; this_ptr [1] = 2; . . . this_ptr [9] = 10; This works fine, but I really don't know why?? It seems you're using memory to store an array which was never really allocated. If anybody could briefly explain what exactly happens when you do this, I'd be greatly abliged as at this point I'm mystified. Thanks alot --> Rob rg2c@andrew.cmu.edu
henry@zoo.toronto.edu (Henry Spencer) (02/10/91)
In article <EbhAAgG00WBNM2PIt_@andrew.cmu.edu> rg2c+@andrew.cmu.edu (Robert Nelson Gasch) writes: >What happens if I do the following? Basically I don't really understand >*why* this works: > > int *this_ptr; > this_ptr [0] = 1; > this_ptr [1] = 2; > . . . > this_ptr [9] = 10; > >This works fine, but I really don't know why?? It seems you're using >memory to store an array which was never really allocated... Precisely correct. What is happening is that on your machine, whatever value this_ptr happens to get as its initial value happens to point to some memory that you are allowed to write on. You're scribbling on a random piece of memory, and random things could happen as a result. Well-designed machines try to make this a catastrophic error. -- "Read the OSI protocol specifications? | Henry Spencer @ U of Toronto Zoology I can't even *lift* them!" | henry@zoo.toronto.edu utzoo!henry
mike (02/11/91)
In an article, andrew.cmu.edu!rg2c+ (Robert Nelson Gasch) writes: >What happens if I do the following? Basically I don't really understand >*why* this works: > > int *this_ptr; > this_ptr [0] = 1; > this_ptr [1] = 2; > . . . > this_ptr [9] = 10; You are writing to some random memory location, and the reaction varies dependant on the operating system and/or hardware. One thing to point out is that pointers and arrays are _not_ interchangable entities _except_ when you are passing them to functions. The moral is this: when you mean to use a pointer, use a pointer; when you mean to use an array, use an array. -- Michael Stefanik | Opinions stated are not even my own. Systems Engineer, Briareus Corporation | UUCP: ...!uunet!bria!mike ------------------------------------------------------------------------------- technoignorami (tek'no-ig'no-ram`i) a group of individuals that are constantly found to be saying things like "Well, it works on my DOS machine ..."
pgt@hpfcso.FC.HP.COM (Paul G. Tobin) (02/15/91)
Michael Stefanik wrote: * One thing to point out is that pointers and arrays are _not_ interchangable * entities _except_ when you are passing them to functions. The moral is this: * when you mean to use a pointer, use a pointer; when you mean to use an array, * use an array. Michael, can you clarify this a little bit? I thought pointers and arrays in C _were_ interchangeable, which is often quite convenient. On pg. 94 of the original K&R, they state (this is a quote): "In fact, a reference to an array is converted by the compiler to a pointer to the beginning of the array. The effect is that an array name _is_ a pointer expression." On the previous page (93), section 5.3 opens with: "In C, there is a strong relationship between pointers and arrays, strong enough that pointers and arrays really should be treated simultaneously. Any operation which can be achieved by array subscripting can also be done with pointers. The pointer version will in general be faster but, at least to the uninitiated, somewhat harder to grasp immediately." It would seem that today's compilers probably somewhat close the speed gap between array and pointer addressing, but I'd contend that they *can* be freely interchanged. It all depends on your personal style. Use whatever mode seems more suited to the task at hand. Sorry for the drift, but the previous responses have aptly answered the question in the basenote. 3 responses without diverging from the original topic is too much :-). Paul Tobin pgt@hpfipgt.fc.hp.com
Jim.Spencer@p510.f22.n282.z1.mmug.edgar.mn.org (Jim Spencer) (02/15/91)
Robert Nelson Gasch writes in a message to All RNG> int *this_ptr; this_ptr [0] = 1; this_ptr [1] = 2; . . . RNG> this_ptr [9] = 10; RNG> This works fine, but I really don't know why?? It seems you're RNG> using memory to store an array which was never really allocated. RNG> If anybody could briefly explain what exactly happens when you RNG> do this, I'd be greatly abliged as at this point I'm mystified. You are overwriting some memory that probably belongs to something else. It is syntatically correct but you are going to get a big crash eventually. -- Jim Spencer - via The Minnesota Macintosh Users Group UUCP-Fido Gateway UUCP: ...uunet!tcnet!kksys!edgar!mmug!22.510!Jim.Spencer INET: Jim.Spencer@p510.f22.n282.z1.mmug.edgar.mn.org
george@moocow.uucp (George Tirebiter) (02/15/91)
henry@zoo.toronto.edu (Henry Spencer) writes: > In article <EbhAAgG00WBNM2PIt_@andrew.cmu.edu> rg2c+@andrew.cmu.edu (Robert N > >What happens if I do the following? Basically I don't really understand > >*why* this works: > > > > int *this_ptr; > > this_ptr [0] = 1; > > this_ptr [1] = 2; > > . . . > > this_ptr [9] = 10; > > > >This works fine, but I really don't know why?? It seems you're using > >memory to store an array which was never really allocated... > > Precisely correct. What is happening is that on your machine, whatever > value this_ptr happens to get as its initial value happens to point to > some memory that you are allowed to write on. You're scribbling on a > random piece of memory, and random things could happen as a result. > > Well-designed machines try to make this a catastrophic error. For example, Turbo C and MicroSoft C compilers point uninitialized pointers at a copyright message embedded in the executable. Upon exit, the copyright message is checked for integrity and if it is corrupt (i.e., you have written something to a pointer for which memory was never malloc()'d), you get the message "Null pointer assignment". Stupid compiler. At least it's not wasting something "valuable"... ..George L. Tirebiter, American. {ames,apple}!uuwest!moocow!george or {...}uunet!nstar!syscon!moocow!george
gwyn@smoke.brl.mil (Doug Gwyn) (02/16/91)
In article <7060009@hpfcso.FC.HP.COM> pgt@hpfcso.FC.HP.COM (Paul G. Tobin) writes: >It would seem that today's compilers probably somewhat close the speed >gap between array and pointer addressing, but I'd contend that they >*can* be freely interchanged. It all depends on your personal style. >Use whatever mode seems more suited to the task at hand. No, it is important to understand that pointers and arrays are NOT freely interchangeable, in order to avoid programming errors. In most (but not all) expression contexts, the name of an array is converted by the compiler to a pointer to the first element of the array, and that pointer is used in the subsequent evaluation. An important exception is when the array name is the operand of the "sizeof" operator; in such a situation the result of evaluation the "sizeof" unary expression is the number of bytes in the entire array, not the number of bytes in a pointer to an element of the array (the latter is typically always 4, in many implementations). The exact rules are spelled out in the C standard, and in A.7.1 in the second edition of K&R these rules are summarized. In the first edition these rules do not seem to have been explained, although certainly some of the exceptions were enforced by existing compilers used as a basis for the notion of what the C language definition was at the time of preparation of the first edition of K&R. The main new feature added for ANSI C is that the & operation can be applied in a more menaingful way to an array (name) than was true for many older existing C implementations.
scs@adam.mit.edu (Steve Summit) (02/16/91)
In article <7060009@hpfcso.FC.HP.COM> pgt@hpfcso.FC.HP.COM (Paul G. Tobin) writes: >Michael Stefanik wrote: >* One thing to point out is that pointers and arrays are _not_ interchangable >* entities _except_ when you are passing them to functions. > > Michael, can you clarify this a little bit? I thought >pointers and arrays in C _were_ interchangeable... It never ends. This time, at least, the confusion is not over the difference between pointers and arrays, but over the interpretation of the word "interchangeable." Michael Stefanik's statement had to do with the fact that the declarations extern char a[]; and extern char *a; are not interchangeable, which is a frequent misunderstanding and is discussed at length in the comp.lang.c Frequently Asked Questions list. It doesn't appear that Paul Tobin is unclear on this point; I think he is noting that a program which declares char a[10]; and then makes reference, in an expression, to a[3] can be rewritten to make "a" a pointer: char *a = malloc(10); without any change to the array-like reference. (This is the same point I made in a recent article about realloc.) Actually, there is a change: the compiler emits different code; but the source code for the reference stays the same. I trust we don't need to discuss any of this again right now. Steve Summit scs@adam.mit.edu
tomkwong@banana.ucsb.edu (Thomas K. Kwong) (02/22/91)
In article <EbhAAgG00WBNM2PIt_@andrew.cmu.edu> rg2c+@andrew.cmu.edu (Robert Nelson Gasch) writes: > > int *this_ptr; > this_ptr [0] = 1; > this_ptr [1] = 2; > . . . > this_ptr [9] = 10; > >This works fine, but I really don't know why?? It seems you're using >memory to store an array which was never really allocated. If anybody >could briefly explain what exactly happens when you do this, I'd be >greatly abliged as at this point I'm mystified. An array subscript is really a shorthand of a pointer notation: a[i] is exactly the same as *(a+i) This conversion is done in compile time, so what you're doing is just using the space allocated in previous malloc() statement. -Thomas. ============================================================ * o | * -------------------- ----- |- * tomkwong@cs.ucsb.edu \/ | * 6600tom@ucsbuxa.edu -------- -- * -------------------- __ | * | | |-- * "Good work does not make a good |--| |-- * man, but a good man does good |--| |-- * work." | | |-- * -Martin Luther \| ------\ * * :-) :-) :-) :-) :-) :-) :-) :-) ============================================================
xwang@gmuvax2.gmu.edu (Xiang-Min Wang) (03/02/91)
In article <9304@hub.ucsb.edu> tomkwong@banana.UUCP (Thomas K. Kwong) writes: >In article <EbhAAgG00WBNM2PIt_@andrew.cmu.edu> rg2c+@andrew.cmu.edu (Robert Nelson Gasch) writes: >> >> int *this_ptr; >> this_ptr [0] = 1; >> this_ptr [1] = 2; >> . . . >> this_ptr [9] = 10; >> >>This works fine, but I really don't know why?? It seems you're using >>memory to store an array which was never really allocated. Please notice that althouhg the pointer 'this_ptr', after declared, is not initialized by YOU (I am not sure the C compiler will initialize it to zero or not), it bears some value (as an address) ANYWAY. Therefore, you can do the "normal" things to it like the assignment: this_ptr[i] = i (or *(this_ptr+i) = i ) Simply speaking, your program is SYNTACTICALLY correct, but FUNCTIONALLY wrong. xwang internet: xwang@gmuvax2.gmu.edu bitnet: xwang@gmuvax.gmu.edu