[comp.lang.c] Array question

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