By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,347 Members | 2,120 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,347 IT Pros & Developers. It's quick & easy.

Address of address

P: n/a
If I have an array of int:

int array[8];

I suppose the correct way to clear it using memset() would be:
memset(array, 0, 8 * sizeof(int));

However, I've seen the following in a piece of code:
memset(&array, 0, 8 * sizeof(int));

What does (or shall) the compiler do in this case? Is the behaviour defined?

/Krister
Sep 19 '06 #1
Share this Question
Share on Google+
10 Replies


P: n/a
kr*****@kalleanka.se said:
If I have an array of int:

int array[8];

I suppose the correct way to clear it using memset() would be:
memset(array, 0, 8 * sizeof(int));
You can initialise it like this:

int array[8] = {0};

If you need to zero it, then memset is okay provided the array is composed
entirely of integers. If you have floats or pointers in there, maybe in
structs, then memset isn't guaranteed to give them zero values.

Just use: memset(array, 0, sizeof array);

Curiously, this works too:

memset(&array, 0, sizeof array);

Both are correct, for slightly different reasons. (That doesn't mean that
array and &array are synonymous; they aren't.)

Some will prefer the latter choice on idiomatic grounds. And some will
prefer the former - on idiomatic grounds! :-)

However, I've seen the following in a piece of code:
memset(&array, 0, 8 * sizeof(int));
Eesh. Someone's trying hard to make life difficult for themselves.
What does (or shall) the compiler do in this case? Is the behaviour
defined?
Provided it really is an array of int and really does have 8 members, yeah,
that works fine. It's just rather noisy, that's all.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 19 '06 #2

P: n/a

kr*****@kalleanka.se wrote:
If I have an array of int:

int array[8];

I suppose the correct way to clear it using memset() would be:
memset(array, 0, 8 * sizeof(int));
yep, that's swell, until somebody changes the type of "array". Or the
number of elements in it.

Maybe you can think of a better wording of that statement?

>
However, I've seen the following in a piece of code:
memset(&array, 0, 8 * sizeof(int));

What does (or shall) the compiler do in this case? Is the behaviour defined?
The general rule is, the name of an array *is* the address of the
array. This funny shortcut exists because there are NO operations in C
that can take place with the VALUE of a whole array, so an array name
cannot mean "get me the value", so it defaults to "gimme the address".

So you never have to put an ampersand in front of an array name. Many
compilers put out an informative warning if you do so.

This doesnt apply if the array is subscripted! For example, array[1]
is manipulable by C's code generator, so array[1] means the VALUE of
that element. So if you need to pass the address of that element, you
do need an ampersand.

>
/Krister
Sep 19 '06 #3

P: n/a
Ancient_Hacker said:

<snip>
So you never have to put an ampersand in front of an array name.
You do if you want the address of the array.

Many
compilers put out an informative warning if you do so.

This doesnt apply if the array is subscripted! For example, array[1]
is manipulable by C's code generator, so array[1] means the VALUE of
that element. So if you need to pass the address of that element, you
do need an ampersand.
And just maybe that element is itself an array, in which case you are
contradicting yourself.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 19 '06 #4

P: n/a

Richard Heathfield wrote:
Ancient_Hacker said:

<snip>
So you never have to put an ampersand in front of an array name.

You do if you want the address of the array.\
Could you shed some light in this area? What do you get with just the
array name that is in any way different from ampersand followed by the
array name?
Inquiring minds want to know.

Many
compilers put out an informative warning if you do so.

This doesnt apply if the array is subscripted! For example, array[1]
is manipulable by C's code generator, so array[1] means the VALUE of
that element. So if you need to pass the address of that element, you
do need an ampersand.
And just maybe that element is itself an array, in which case you are
contradicting yourself.
No contradiction, I think, I didnt say "pass the address value stored
in that element".

Sep 19 '06 #5

P: n/a
Ancient_Hacker said:
>
Richard Heathfield wrote:
>Ancient_Hacker said:

<snip>
So you never have to put an ampersand in front of an array name.

You do if you want the address of the array.\

Could you shed some light in this area? What do you get with just the
array name that is in any way different from ampersand followed by the
array name?
A different type.

Let's take a nice simple example:

#include "t.h" /* write your own :-) */

T myarray[N] = {0}; /* 1 */

T *p = myarray; /* 2 */

In line 2, the expression myarray is exactly equivalent to &myarray[0],
and yields a value that has type T*. It's the address of the first element
of the array.

size_t arrsize = sizeof myarray; /* 3 */

In line 3, myarray is the operand of sizeof, and sizeof doesn't evaluate its
operands, so myarray refers to the array itself. Thus, arrsize is equal to
N * sizeof(T).

size_t arrptrsize = sizeof &myarray; /* 4 */

In line 4, myarray is the operand of the address operator, which again does
not evaluate its operand. The address thus given has type T (*)[N], and so
the whole expression &myarray yields an expression of that type.
Consequently, that is the expression type that becomes the operand of
sizeof. On a typical modern desktop system, arrptrsize will now hold the
value 4, rather than the value N * sizeof(T).

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 19 '06 #6

P: n/a
Ancient_Hacker wrote:
Richard Heathfield wrote:
>Ancient_Hacker said:

<snip>
So you never have to put an ampersand in front of an array name.

You do if you want the address of the array.\

Could you shed some light in this area? What do you get with just the
array name that is in any way different from ampersand followed by the
array name?
The array name decays (in value context) to the address of its first
element. This is not the same as the address of the array: they have
different types.

#include <stdio.h>

void accept( int *foo ) {}

int main()
{
int foo[2] = {0};
accept( foo );
accept( &foo );
return 0;
}

gcc -ansi -pedantic it.c
it.c: In function 'main':
it.c:9: warning: passing argument 1 of 'accept' from incompatible pointer type

Line 9 is the second call to `accept`.

--
Chris "falling further in" Dollin
A rock is not a fact. A rock is a rock.

Sep 19 '06 #7

P: n/a
posted:
If I have an array of int:

int array[8];

I suppose the correct way to clear it using memset() would be:
memset(array, 0, 8 * sizeof(int));

However, I've seen the following in a piece of code:
memset(&array, 0, 8 * sizeof(int));

The type of the following expression:

array

is int[8]. When used in a context where a pointer is required, it decays to
a pointer to the first element of the array -- thus yielding an expression
of the type int* (which refers to &array[0]).

The type of the following expression:

&array

is int(*)[8], i.e. it is a pointer to an array consisting of eight
elements.

--

Frederick Gotham
Sep 19 '06 #8

P: n/a
Ancient_Hacker posted:
So you never have to put an ampersand in front of an array name. Many
compilers put out an informative warning if you do so.
With regard to a card game (such as poker), let's write a function which
takes as an argument the quantity of cards in a hand which are of a
particular suite; here's one way of doing it:

void AnalyseHand(unsigned const (*const quant_suite)[4])
{

}

int main(void)
{
unsigned const suite[4] = {5,3,7,2};
AnalyseHand(&suite);
}

There's plenty of good uses for a pointer to an array.

--

Frederick Gotham
Sep 19 '06 #9

P: n/a
"Ancient_Hacker" <gr**@comcast.netwrites:
[...]
The general rule is, the name of an array *is* the address of the
array. This funny shortcut exists because there are NO operations in C
that can take place with the VALUE of a whole array, so an array name
cannot mean "get me the value", so it defaults to "gimme the address".
Only if by "general" you mean "incomplete".

The general rule is this (C99 6.3.2.1p3):

Except when it is the operand of the sizeof operator or the unary
& operator, or is a string literal used to initialize an array, an
expression that has type "array of _type_" is converted to an
expression with type "pointer to _type_" that points to the
initial element of the array object and is not an lvalue. If the
array object has register storage class, the behavior is
undefined.
So you never have to put an ampersand in front of an array name. Many
compilers put out an informative warning if you do so.
&array is a perfectly legitimate expression; it yields the address of
the array, which is distict from the address of its first element.
They have the "same value" in some sense, but they're of different
types.

For example, given "int array[10];", the expression "array + 1" is of
type int* and yields the address of the second element of array, and
the expression "&array + 1" is of type int(*)[10] (pointer to array of
10 ints), and yields a pointer just past the end of the object.

Most arrays are accessed via pointers to their elements, so taking the
address of a full array is relatively rare -- but it is meaningful,
and quite distinct from taking the address of an array element.
This doesnt apply if the array is subscripted! For example, array[1]
is manipulable by C's code generator, so array[1] means the VALUE of
that element. So if you need to pass the address of that element, you
do need an ampersand.
On the contrary, the actual rule does apply to subscript operations.
The subscript operator, x[y], is by definition equivalent to *(x + y),
where one operand is a pointer and the other is an integer. In the
expression "array[5]", the expression "array" is implicitly converted
to a pointer. This is just the normal conversion that usually happens
to array expressions; it has nothing to do with the indexing
operation.

Arrays are not pointers. Pointers are not arrays. It's important to
keep this in mind, in spite of the language's best efforts to make you
think otherwise.

See section 6 of the comp.lang.c FAQ, <http://www.c-faq.com/>, "Arrays
and pointers".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Sep 19 '06 #10

P: n/a
Ancient_Hacker wrote:
So you never have to put an ampersand in front of an array name. Many
compilers put out an informative warning if you do so.

This doesnt apply if the array is subscripted! For example, array[1]
is manipulable by C's code generator, so array[1] means the VALUE of
that element.
So if you need to pass the address of that element,
you do
You don't.
need an ampersand.
The address of array[1] is (array + 1).

--
pete
Sep 20 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.