473,387 Members | 1,528 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

confused with sizeof and pointers

Hello,

I am new to C Programming and just started reading K&R. I was about to
finish the pointers chapter but got very confused with:

1. int arr[10];
From what I have read, arr is a pointer to the first int and &arr is a

pointer to the whole array of 10 ints. Then why does sizeof(arr) gives
40 while sizeof(&arr) gives 4. Shouldn't is be the other way around.

2. int arr[2][2]={{1,2},{3,4}};
printf("%u %u",arr,*arr);

produces the same output(base address). But haven't we dereferenced arr
in the second case. I mean, arr is an address to the base of the array
and putting a star in front of should give us the value there.

regards,
vijay.

Nov 14 '05 #1
9 2193
vijay wrote:
Hello,

I am new to C Programming and just started reading K&R. I was about to
finish the pointers chapter but got very confused with:

1. int arr[10];
From what I have read, arr is a pointer to the first int and &arr is a pointer to the whole array of 10 ints.


No, arr and &arr are equivalent. One is a pointer to the first element
of arr[0] and the other is an expression that results in a pointer to
the first element of arr[0]. At least that's how I think of it.
Then why does sizeof(arr) gives
40 while sizeof(&arr) gives 4. Shouldn't is be the other way around.
Answered above, since sizeof arr (no parens need for objects) is the
size of the entire array, you get 40 on your system. Since &arr is an
expression for a pointer to the first element of arr, you should get the
size of a pointer, not the array.
2. int arr[2][2]={{1,2},{3,4}};
printf("%u %u",arr,*arr);

produces the same output(base address). But haven't we dereferenced arr
in the second case. I mean, arr is an address to the base of the array
and putting a star in front of should give us the value there.


Both arr and *arr are pointers, arr is a pointer to a pointer to int and
*arr is a pointer to int. They should be the same in this case since
they both point to arr[0][0]. You should also use this syntax for pointers:

printf("%p %p\n", (void *) arr, (void *) *arr);

- Mark
Nov 14 '05 #2


vijay wrote:
Hello,

I am new to C Programming and just started reading K&R. I was about to
finish the pointers chapter but got very confused with:

1. int arr[10];
From what I have read, arr is a pointer to the first int and &arr is a

pointer to the whole array of 10 ints. Then why does sizeof(arr) gives
40 while sizeof(&arr) gives 4. Shouldn't is be the other way around.

2. int arr[2][2]={{1,2},{3,4}};
printf("%u %u",arr,*arr);

produces the same output(base address). But haven't we dereferenced arr
in the second case. I mean, arr is an address to the base of the array
and putting a star in front of should give us the value there.


Section 6 of the comp.lang.c Frequently Asked
Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

may help you understand this better. Read it, and
post again if you are still confused.

--
Er*********@sun.com

Nov 14 '05 #3


Mark Odell wrote:
vijay wrote:
Hello,

I am new to C Programming and just started reading K&R. I was about to
finish the pointers chapter but got very confused with:

1. int arr[10];
From what I have read, arr is a pointer to the first int and &arr is apointer to the whole array of 10 ints.

No, arr and &arr are equivalent. One is a pointer to the first element
of arr[0] and the other is an expression that results in a pointer to
the first element of arr[0]. At least that's how I think of it.


Perhaps you should adjust your thinking by pondering
Question 6.12 in the comp.lang.c Frequently Asked Questions
(FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html
[Remainder of Mark's post snipped; it indicates that he
is just as confused as is Vijay.]


--
Er*********@sun.com

Nov 14 '05 #4
"vijay" <Ta***********@yahoo.com> writes:
I am new to C Programming and just started reading K&R. I was about to
finish the pointers chapter but got very confused with:

1. int arr[10];

From what I have read, arr is a pointer to the first int and &arr is a
pointer to the whole array of 10 ints. Then why does sizeof(arr) gives
40 while sizeof(&arr) gives 4. Shouldn't is be the other way around.
The C FAQ is at <http://www.eskimo.com/~scs/C-faq/faq.html>. Read
section 6, "Arrays and Pointers".

Briefly, when an array name appears in an expression, it's usually,
but not always, converted to a pointer to its first element. When it
appears as the operand of a unary "&" or sizeof operator, this
conversion doesn't happen. That's why "sizeof(arr)" (or "sizeof arr";
the parentheses aren't necessary) gives you the size of the whole
array, not the size of a pointer, and "&arr" gives you a pointer to
the whole array (which is like a pointer to its first element except
for the type).
2. int arr[2][2]={{1,2},{3,4}};
printf("%u %u",arr,*arr);

produces the same output(base address). But haven't we dereferenced arr
in the second case. I mean, arr is an address to the base of the array
and putting a star in front of should give us the value there.


Here you're invoking undefined behavior by calling printf() with a
"%u" format, but not passing a value of type unsigned int. It may
happen to work on your system (if unsigned ints and pointers happen to
be passed as arguments the same way), but it's not guaranteed. To
print a pointer value, use the "%p" format. Since "%p" expects a
void*, you need to convert the argument explicitly (there's no
implicit conversion in this case).

So try this:

int arr[2][2]={{1,2},{3,4}};
printf("%p %p\n", (void*)arr, (void*)*arr);

arr is of type array[2] of array[2] of int.

For the second argument to printf(), arr decays to a pointer to an
array[2] of int; converting to void* gives you a pointer usable with
"%p".

For the third argument, arr again decays to a pointer to an array[2]
of int. Applying the "*" operator gives you an array[2] of int, which
then decays to a pointer to int. (I think that's right; if not,
someone will jump in and correct me.) It points to the same memory
location as the second argument, but with a different type.

So the second argument points to arr[2], an array of 2 ints, and the
third argument points to arr[2][2], an int. Both are at the same
address.

Here's a program that might demonstrate more clearly what's going on,
using a function that expects arguments of the appropriate types:

#include <stdio.h>

static void print_values(int (*arg1)[2], int *arg2)
{
printf("%p %p\n", (void*)arg1, (void*)arg2);
}

int main(void)
{
int arr[2][2]={{1,2},{3,4}};
printf("%p %p\n", (void*)arr, (void*)*arr);
print_values(arr, *arr);
return 0;
}

--
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.
Nov 14 '05 #5
Mark Odell <od*******@hotmail.com> writes:
[...]
No, arr and &arr are equivalent. One is a pointer to the first element
of arr[0] and the other is an expression that results in a pointer to
the first element of arr[0]. At least that's how I think of it.
Correction: a pointer to the first element of arr, not to the first
element of arr[0].

[...] Both arr and *arr are pointers, arr is a pointer to a pointer to int
and *arr is a pointer to int. They should be the same in this case
since they both point to arr[0][0]. You should also use this syntax
for pointers:
arr is an array, not a pointer; it's implicitly converted to a pointer
when used in an expression (in most contexts).

There is no pointer-to-pointer-to-int here. What arr decays to (i.e.,
is implicitly converted to) is a pointer to an array, not a pointer to
a pointer.
printf("%p %p\n", (void *) arr, (void *) *arr);


Yes.

--
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.
Nov 14 '05 #6
No, arr and &arr are equivalent.
Nope. Their types are different. For most implementations,
their actual values are likely to be the same, but there are no
guarantees.
One is a pointer to the first element
of arr[0] and the other is an expression that results in a pointer to
the first element of arr[0]. At least that's how I think of it.

Correction: a pointer to the first element of arr, not to the first
element of arr[0].


A legal standalone 'arr' is equivalent to &arr[0] except when it
is the operand of a sizeof. Both are of type (type_of_arr_element *)
and point to the first element of 'arr'.
&arr has type
(pointer to array of type same as 'arr'). It points to the beginning of
the array 'arr'.
The actual rules are more subtle - in particular when used
as function arguments, 'arr' doesn't decay to a pointer, it gets
adjusted to be a pointer. In practice, the above info suffices.

--
www.stanford.edu/people/ajoyk
Nov 14 '05 #7
On Thu, 17 Mar 2005 16:59:57 -0800, Ajoy K Thamattoor
<aj***@cs.stanford.edu> wrote:
[ about int arr[2][2] ]
No, arr and &arr are equivalent.
Nope. Their types are different. For most implementations,
their actual values are likely to be the same, but there are no
guarantees.
Exceedingly likely; there are no guarantees, but AFAIK we in c.l.c
know of no exceptions. (We _do_ know of exceptions to the also
unguaranteed assumption that all data pointers, or even all pointers,
are the same.)
One is a pointer to the first element
of arr[0] and the other is an expression that results in a pointer to
the first element of arr[0]. At least that's how I think of it.

Correction: a pointer to the first element of arr, not to the first
element of arr[0].

arr evaluates to a pointer to the first element of arr, that is the
row arr[0]. &arr evaluates to a pointer to the whole array, not the
first element or any other, although as above in practice the whole
array is at the same address as its first element(s).
A legal standalone 'arr' is equivalent to &arr[0] except when it
is the operand of a sizeof. Both are of type (type_of_arr_element *)
and point to the first element of 'arr'.
Right.
&arr has type
(pointer to array of type same as 'arr'). It points to the beginning of
the array 'arr'.
Almost right; it points to the whole array, which as above in practice
is at the same address.
The actual rules are more subtle - in particular when used
as function arguments, 'arr' doesn't decay to a pointer, it gets
adjusted to be a pointer. In practice, the above info suffices.


Use as function (actual) argument isn't different; it decays just like
any expression. You may be thinking of the _declaration_ of function
(dummy) _parameters_ where a parameter declared as array of T is
adjusted to pointer to T -- and is therefore the correct type to
receive an argument which was an array that decayed to pointer to
element. (And similarly a parameter declared as a function type is
adjusted to a pointer to that function type.)

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #8
Dave Thompson wrote:
On Thu, 17 Mar 2005 16:59:57 -0800, Ajoy K Thamattoor
<aj***@cs.stanford.edu> wrote:
[ about int arr[2][2] ]
No, arr and &arr are equivalent.


Nope. Their types are different. For most implementations,
their actual values are likely to be the same, but there are no
guarantees.


Exceedingly likely; there are no guarantees, but AFAIK we in c.l.c
know of no exceptions. (We _do_ know of exceptions to the also
unguaranteed assumption that all data pointers, or even all pointers,
are the same.)


We also know of C implementations where `arr + 1' and
`&arr + 1' are not at all alike -- namely, every single C
implementation imaginable ...

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 14 '05 #9
Dave Thompson wrote:

On Thu, 17 Mar 2005 16:59:57 -0800, Ajoy K Thamattoor
<aj***@cs.stanford.edu> wrote:
[ about int arr[2][2] ]
>No, arr and &arr are equivalent.


Nope. Their types are different. For most implementations,
their actual values are likely to be the same, but there are no
guarantees.

Exceedingly likely; there are no guarantees,


Wrong. There is a guarantee.
((char *)arr == (char *)&arr)
is guaranteed true when arr is an array.

Is 0 equal to 0u?
Their types are different and the comparison can't be done
without a conversion of the int type expression to unsigned.

--
pete
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

13
by: Richard | last post by:
vector<char*> m_Text; m_Text.resize(1); char* foo = "FOO"; char* bar = "BAR"; char* foobar = (char*)malloc(strlen(foo) + strlen(bar) + 1); if (foobar) { strcpy(foobar, foo); strcat(foobar,...
15
by: signuts | last post by:
I'm aware of what sizeof(...) does, what I would like to know is if sizeof(...) is compiled in or a function that's executed at run-time. Like for example { int a; printf("a is %d...
34
by: Richard Hunt | last post by:
I'm sorry for asking such a silly question, but I can't quite get my head around malloc. Using gcc I have always programmed in a lax C/C++ hybrid (which I suppose is actually c++). But I have...
2
by: Kevin C. | last post by:
Can someone explain why the file output produces all zeros? It seems to work fine in memory (e.g. passing char pointers to printf) but when I output the file, it comes out as zeros. Bookkeeping...
6
by: Amigo | last post by:
Hello all! I started working on an embedded project a few ago on Freescale 16-bit micro with an IAR toolset. Running PolySpace for the project code highlighted amongst other things a peculiar...
38
by: James Brown | last post by:
All, I have a quick question regarding the size of pointer-types: I believe that the sizeof(char *) may not necessarily be the same as sizeof(int *) ? But how about multiple levels of pointers...
19
by: arnuld | last post by:
i am trying to understand arrays and char. Stroustrup says, this a string literal: "this is a string literal" he says it is of type /const char/. he also says, because of keeping...
17
by: kevin | last post by:
this is my programm .... char *p="abcde"; char a="abcde"; ..... printf("the size of p is:%d\n",sizeof(p)); printf("the size of a is:%d\n",sizeof(a)); ........
16
by: Alex Vinokur | last post by:
Does it have to be? : sizeof (size_t) >= sizeof (pointer) Alex Vinokur email: alex DOT vinokur AT gmail DOT com http://mathforum.org/library/view/10978.html http://sourceforge.net/users/alexvn
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.