Newbie Question: 'Sizeof' - I'm unclear what it actually measures,Modern equiv of older style refer


L

Laurel Shimer

Working to develop comfort with the language,I have been typing up
and running the code examples, and thinking through each line in each
example to make sure I know what each command is doing. Then I try to
make up my own very simple examples in the style of the ones in the
book.

(actually I have 3 books I go between, trying things out, and figuring
out my personal study plan. I tend to work within a particular book
for a couple of weeks. I return back once another author has gotten
me over a stumbling block - self-study ain't easy)

I'm currently working in the most basic of the 3 books ("Objective -C"
A Visual Quickstart Guide by Steve Holzner )
I'm using and I got stuck understanding how 'sizeof' works. (See also
my question below about my needing to figure out how to use
documentation better)

......
The author says that sizeof gets "the size of the whole array". I can
see from displaying each piece of the information that the author
uses, that the calculation using sizeof works, but I don't get what
'sizeof' is sizing? Is is the number of digits it allocates for each
instance in the array?

(the example in the book did not cast - is that the right way to say
it?- but I got compiler warnings and so I added the (long) part). Hope
I have gotten that idea right.

I added the second 2 printf statements. The author clearly thinks I
should be able to figure it out from the first one, which I haven't so
far.

............

#include <stdio.h>

int main()
{
int scores[5] = {92, 72, 57, 98, 89};

printf ("The array is %i elements long.\n", (long) sizeof(scores) /
(long) sizeof(int));

printf ("sizeof(scores) is %i \n", (long) sizeof(scores) );

printf ("(long) sizeof(int) is %i\n", (long) sizeof(int));

return 0;

}
Running…
The array is 5 elements long.
sizeof(scores) is 20
(long) sizeof(int) is 4

Debugger stopped.
Program exited with status value:0.

............. Second question Modern Equiv of older style reference
manual?........

ALSO this brings up one of my challenges. In my history I always had a
nice big fat reference manual where I could look up everything. (I
admit that even in unix, I like a reference manual - though I know how
to do man pages) My guess is that now, I'm supposed to be looking more
at online documentation or documentation within the application
(XCODE) that I'm using. I have a feeling I'm missing something big by
not quite knowing where to go.

I did find the folders with the foundation framework in XCODE, so
that when I go back to working on the OOP side (which I have
temporarily put on the back burner - since I realized I was fighting
my procedural programmer mindset), but that doesn't seem to be where I
find documentation on FUNCTIONS like ' sizeof'.

Thanks for steering my footsteps

Laurel
 
Ad

Advertisements

R

Richard

[Please do not mail me a copy of your followup]

Sizeof measures the storage, in bytes, of its argument.

char c;
assert(sizeof(c) == 1);
int i;
assert(sizeof(i) == 4); // for 32-bit ints
 
L

Laurel Shimer

Working to develop comfort with the language,I have been  typing up
and running the code examples, and thinking through each line in each
example to make sure I know what each command is doing. Then I try to
make up my own very simple examples in the style of the ones in the
book.

(actually I have 3 books I go between, trying things out, and figuring
out my personal study plan. I tend to work within a particular book
for a couple of weeks. I  return back once another author has gotten
me over a stumbling block - self-study ain't easy)

I'm currently working in the most basic of the 3 books ("Objective -C"
A Visual Quickstart Guide by Steve Holzner )
I'm using and I got stuck understanding how 'sizeof' works. (See also
my question below about my needing to figure out how to use
documentation better)

.....
The author says that sizeof gets "the size of the whole array". I can
see from displaying each piece of the information that the author
uses, that the calculation using sizeof works, but I don't get what
'sizeof' is sizing? Is is the number of digits it allocates for each
instance in the array?

(the example in the book did not cast - is that the right way to say
it?- but I got compiler warnings and so I added the (long) part). Hope
I have gotten that idea right.

I added the second 2 printf statements. The author clearly thinks I
should be able to figure it out from the first one, which I haven't so
far.

...........

#include <stdio.h>

int main()
{
        int scores[5] = {92, 72, 57, 98, 89};

        printf ("The array is %i elements long.\n", (long) sizeof(scores) /
(long) sizeof(int));

        printf ("sizeof(scores) is %i \n", (long) sizeof(scores)  );

        printf ("(long) sizeof(int) is %i\n",  (long) sizeof(int));

        return 0;

}

Running…
The array is 5 elements long.
sizeof(scores) is 20
(long) sizeof(int) is 4

Debugger stopped.
Program exited with status value:0.

............ Second question Modern Equiv of older style reference
manual?........

ALSO this brings up one of my challenges. In my history I always had a
nice big fat reference manual where I could look up everything. (I
admit that even in unix, I like a reference manual - though I know how
to do man pages) My guess is that now, I'm supposed to be looking more
at online documentation or documentation within the application
(XCODE) that I'm using. I have a feeling I'm missing something big by
not quite knowing where to go.

 I did find the folders with the foundation framework in XCODE, so
that when I go back to working on the OOP side (which I have
temporarily put on the back burner - since I realized I was fighting
my procedural programmer mindset), but that doesn't seem to be where I
find documentation on FUNCTIONS like ' sizeof'.

Thanks for steering my footsteps

Laurel

Sorry for final edit errors. I can't find a way to cleanup my original
post so that it looks like I can actually speak and write in English.
 
B

Balog Pal

Laurel Shimer said:
where I find documentation on FUNCTIONS like ' sizeof'.

Did you consider STFW?

google's first hit on 'sizeof' looks damn promising to me...
 
L

Laurel Shimer

Did you consider STFW?

google's first hit on 'sizeof' looks damn promising to me...


Thank you for your kind suggestion. Actually I did search the gosh-
darned web, though clearly I included too many arguments. The
wikipedia you so politely pointed out to me, is useful. I can see I
might have understood sizeoff better. I also understand it now that I
saw Richard's response. The lightbulb went on and I realized I was
actually measuring the size of the datatype 'int', which I hadn't sunk
in. Though it seems extremely clear now - funny how that's always the
case.

What I'm asking is, do I rely on Wikipedia to lookup a basic
explanation of a function in Objective-C? Or is there a reference
source that people who have been using the language longer than I
have, all know about? Something I've no doubt missed as I begin
studying a new language and a different programming environment.

Laurel
 
I

Ian Collins

ALSO this brings up one of my challenges. In my history I always had a
nice big fat reference manual where I could look up everything. (I
admit that even in unix, I like a reference manual - though I know how
to do man pages) My guess is that now, I'm supposed to be looking more
at online documentation or documentation within the application
(XCODE) that I'm using. I have a feeling I'm missing something big by
not quite knowing where to go.

If you want a big fat comprehensive reference manual, get a copy of the
standard.
I did find the folders with the foundation framework in XCODE, so
that when I go back to working on the OOP side (which I have
temporarily put on the back burner - since I realized I was fighting
my procedural programmer mindset), but that doesn't seem to be where I
find documentation on FUNCTIONS like ' sizeof'.

Another common newbie mistake - sizeof is *not* a function, it is an
operator.

http://www.cplusplus.com/reference/ is a reasonable on-line reference.
 
Ad

Advertisements

R

Richard

[Please do not mail me a copy of your followup]

Christian Hackl <[email protected]> spake the secret code
In C++, the correct way to create an array of 5 ints and print its size
is as follows:

std::vector<T> is a dynamic array.

Fixed-size arrays are perfectly fine in C++ and the syntax of
aggregate initialization from C is also perfectly fine.

sizeof() is what you want to tell you the size of a fixed-size array,
i.e. sizeof(array_)/sizeof(array_[0])
 
R

Richard

[Please do not mail me a copy of your followup]

Laurel Shimer <[email protected]> spake the secret code
What I'm asking is, do I rely on Wikipedia to lookup a basic
explanation of a function in Objective-C?

Objective C is neither C nor C++. It is its own dialect. Use Apple's
reference documentation to look up stuff on Objective C.
 
J

Joshua Maurice

If you want a big fat comprehensive reference manual, get a copy of the
standard.

The standard is useful for some more arcane topics (sometimes, maybe),
but I strongly suggest not getting the standard as a beginner.
cplusplus.com works well for a standard library reference. There's
sgi's site too. As for a language reference, I'm not quite sure, but I
would think that there are more readable, understandable, and \maybe
even applicable\ documents out there than the official C++ standard.
 
I

Ian Collins

The standard is useful for some more arcane topics (sometimes, maybe),
but I strongly suggest not getting the standard as a beginner.

Maybe, it is a reference, not a tutorial and a tutorial is more use to a
beginner.
cplusplus.com works well for a standard library reference. There's
sgi's site too. As for a language reference, I'm not quite sure, but I
would think that there are more readable, understandable, and \maybe
even applicable\ documents out there than the official C++ standard.

"The C++ Programming Language" is a good start for the language and an
introduction to the standard library. "The C++ Standard Library" by
Nicolai Josuttis is an invaluable guide the the Standard Library.
 
T

The Simple Romantic

Richard ha scritto:
Christian Hackl <[email protected]> spake the secret code
<[email protected]> thusly:
std::vector<T> is a dynamic array.
Fixed-size arrays are perfectly fine in C++ [...]

Well, try to return one from a function. Or pass one by reference.
That's not exactly "pefectly fine". Arrays are a broken language
construct, and beginners should just not be exposed to them at all.

--
Christian Hackl
(e-mail address removed)

Milano 2008/2009 -- L'Italia chiamò, sì!

Thank you to everybody who who responded.

I got several good ideas here. And it helps to see what people
disagree about. I'll just keep plugging away, keeping in mind that no
book is going to be perfect - no doubt I will learn some things that
aren't the way I ought to work, which is why I've been going back and
forth between books. At the same time, I have to stick with each book
for awhile or I get nowhere. So if I end up later on saying that
something was worthless, or led me down the wrong path, at least I
went somewhere and learned something.

I just wrote up my revised study plan for how long to continue using
this book before returning to the other two books. I'm doing this one
now because the examples are very short and simple. The examples in
the other ones get complicated quickly. Also I know I need to take a
time-out to just work on developing the object oriented mindset. But I
want to, at least, work through the examples in this more simplistic
book before I do that.

Laurel
 
Ad

Advertisements

G

Gennaro Prota

Working to develop comfort with the language,I have been typing up
and running the code examples, and thinking through each line in each
example to make sure I know what each command is doing. Then I try to
make up my own very simple examples in the style of the ones in the
book.

(actually I have 3 books I go between, trying things out, and figuring
out my personal study plan. I tend to work within a particular book
for a couple of weeks. I return back once another author has gotten
me over a stumbling block - self-study ain't easy)

I'm currently working in the most basic of the 3 books ("Objective -C"
A Visual Quickstart Guide by Steve Holzner )

Ok, stop here, please :) This newsgroup is about C++, which is
a different language. It's not that we don't want to help,
really, or nitpick: the issue is that languages may be subtly
different. Most of the replies I've seen in this thread seem to
have missed this.

[...]
#include <stdio.h>

int main()
{
int scores[5] = {92, 72, 57, 98, 89};

printf ("The array is %i elements long.\n", (long) sizeof(scores) /
(long) sizeof(int));

printf ("sizeof(scores) is %i \n", (long) sizeof(scores) );

printf ("(long) sizeof(int) is %i\n", (long) sizeof(int));

return 0;

}
Running…
The array is 5 elements long.
sizeof(scores) is 20
(long) sizeof(int) is 4

If this were C++ or C (which is yet another language) the "%i"
in the first argument to printf would tell that you want to
output an int. For a long, you'd have to replace it with "li".
Also, what type the result of sizeof has, could change from one
platform to another (although it would always be unsigned).

Given that you want to know about a different language, I won't
go into further details.

[other questions snipped...]

I searched on my NNTP server and saw that there's a newsgroup
with name comp.lang.objective-c. You should probably ask your
questions there.

About Wikipedia, which you mentioned in another post, it is no
reliable reference in general, as pretty much anything on the
web. However it contains lots of info and, if you are careful,
you can discern the correct and useful stuff from the rest (just
like on newsgroups).

Good luck with your learning.
 
J

Juha Nieminen

Christian Hackl said:
In C++, the correct way to create an array of 5 ints and print its size
is as follows: [...]
std::vector<int> scores;

Says who?

If I say that the "correct" way of create such an array is by using
std::deque, are you going to say that I'm wrong?

Using std::vector is only one possible way of doing that. On what grounds
do you base your claim that it's "the correct way"?

Besides, suggesting using std::vector in all possible cases is
irresponsible. If you want an array of exactly 5 ints, and it will be
an array of 5 ints for the entire duration of the program, then
std::vector is one of the least efficient ways of doing that. This is
especially true if it will be instantiated many times, for example as
the member of a class (which is instantiated and copied around a lot).

If I needed an array of exactly 5 ints in a class, I would very definitely
write it as:

class TheClass
{
int theArray[5]; // The *correct* way
...
};

and very definitely not as:

class TheClass
{
std::vector<int> theArray; // The *incorrect* way
...
};

As said, if an array of exactly 5 ints is needed, using std::vector for
that is an extremely inefficient solution.
Note that what some other languages usually call "array" is called
"std::vector" in C++.

Again, says who?

If I used std::deque instead, would you claim I'm wrong? On what do you
base your claim on?
IOW, it's the language's default container.

Default container? Where does it say that?
A vector knows its own size and does not require you to cast anything.

Neither does std::deque. Why are you shunning it?
The thing you have used are "real", or low-level, arrays. You usually do
not need them in C++, especially when you are a beginner. They will get
you into a lot of trouble and gain you nothing.

If the array has a fixed size and is small, using an array rather than
std::vector is definitely more efficient (regardless of the context).
How is that "gain you nothing"?
 
J

Juha Nieminen

Christian Hackl said:
Well, try to return one from a function. Or pass one by reference.

Arrays themselves cannot be handled "by value" (which makes them a bit
different from all the other constructs), but you can get around that
limitation by embedding the array inside a struct. Then you can handle
it "by value" all you want. You can return it from a function, pass it
to functions by value, and pass references to it.
That's not exactly "pefectly fine". Arrays are a broken language
construct, and beginners should just not be exposed to them at all.

Too bad that arrays happen to be the most memory-efficient constructs
in existence (for storing sequential data). They consume the minimum
amount of memory (for raw data; exotic data containers which somehow
use compression techniques for storing the data are a story of their
own) and they are usually extremely fast to instantiate in many situations
(eg. because they are basically the only "data container" that can be
allocated on the stack, alongside POD structs, if you want to consider
them "data containers" as well).
 
F

Francesco S. Carta

<questions about managing raw arrays>

I wonder why nobody pointed out that we can simply wrap raw arrays into
a template in order to bring along their sizes, and we can do that quite
easily too.

It took me way more time to come up with the silly test case than to
write the actual wrapper:

//-------
// in some header or hidden in an implementation file
// with fitting explicit instantiations in an appropriate header
// (or maybe exported, if you're lucky)
// this can be, of course, widely extended and improved

template <class T, int SIZE> class Array {
public:
T& operator[](int index) {
return data[index];
}
const T& operator[](int index) const {
return data[index];
}
int size() const {
return SIZE;
}
private:
T data[SIZE];
};

//-------

//-------
// really silly test case

#include <iostream>
#include <iomanip>
#include <cassert>

// include the appropriate header or paste the template here

using namespace std;

template<class T> void MultiplyMatrixIndices(T& matrix) {
for (int y = 0; y < matrix.size(); ++y) {
for (int x = 0; x < matrix[y].size(); ++x) {
matrix[y][x] = x * y;
}
}
}

template<class T> void PrintMatrix(const T& matrix) {
const int W = 3;
cout << right << setw(W) << "x*y";
for (int x = 0; x < matrix[0].size(); ++x) {
cout << setw(W) << x;
}
cout << endl;

for (int y = 0; y < matrix.size(); ++y) {
cout << setw(W) << y;
for (int x = 0; x < matrix[y].size(); ++x) {
cout << setw(W) << matrix[y][x];
}
cout << endl;
}
}

int main() {
const int index1 = 7;
const int index2 = 8;

Array< Array<int, index2>, index1> m;

MultiplyMatrixIndices(m);
PrintMatrix(m);

return 0;
}

//-------
 
R

Richard

[Please do not mail me a copy of your followup]

(e-mail address removed) spake the secret code
<questions about managing raw arrays>

I wonder why nobody pointed out that we can simply wrap raw arrays into
a template in order to bring along their sizes, and we can do that quite
easily too.

Boost.Range abstracts away the differences between STL containers,
pairs of iterators and raw arrays. This lets you do things like:

template <typename C, typename I>
bool contains(C & collection, const I & item)
{
return std::find( boost::begin( collection ),
boost::end( collection ), item )
!= boost::end( collection);
}

int p[] = { 5, 4, 3, 2, 1 };
assert(contains(p, 3));

The most common case of using algorithms like std::find is to use
c.begin() and c.end() as the iterator pair, but using Boost.Range I
can factor out that duplication into a "contains" function that will
work on any container including raw arrays.
 
Ad

Advertisements

F

Francesco S. Carta

[Please do not mail me a copy of your followup]

(e-mail address removed) spake the secret code
<questions about managing raw arrays>

I wonder why nobody pointed out that we can simply wrap raw arrays into
a template in order to bring along their sizes, and we can do that quite
easily too.

Boost.Range abstracts away the differences between STL containers,
pairs of iterators and raw arrays. This lets you do things like:

template<typename C, typename I>
bool contains(C& collection, const I& item)
{
return std::find( boost::begin( collection ),
boost::end( collection ), item )
!= boost::end( collection);
}

int p[] = { 5, 4, 3, 2, 1 };
assert(contains(p, 3));

The most common case of using algorithms like std::find is to use
c.begin() and c.end() as the iterator pair, but using Boost.Range I
can factor out that duplication into a "contains" function that will
work on any container including raw arrays.

But not including raw pointers, which is what we get as soon as we try
to pass a raw array around.

I'm just advocating the usefulness of wrapping raw arrays, I am in no
way criticizing your contribution, which I share and support.
 
J

Juha Nieminen

Christian Hackl said:
Juha Nieminen ha scritto:
Christian Hackl said:
In C++, the correct way to create an array of 5 ints and print its size
is as follows: [...]
std::vector<int> scores;

Says who?

If I say that the "correct" way of create such an array is by using
std::deque, are you going to say that I'm wrong?

Yes, because it goes against experience and common sense.

Exactly how does it go against "experience and common sense"?

An array is a sequential data container which can be indexed in constant
time. Both std::vector and std::deque fulfill that requirement. You can
traverse an array in linear time, and both std::vector and std::deque
fulfill that requirement. If we are talking about dynamic arrays, where
you can add and remove elements at will, both std::vector and std::deque
fulfill that requirement. They even have the same computational complexity
for doing so (at least when appending data to the end or insertinging data
to the middle). They even have similar iterator invalidation behavior.

The one major difference between the two is that you can insert elements
to the beginning of a std::deque in constant time, while with std::vector
that would be a linear-time operation. However, that hardly disqualifies
std::deque as a valid substitute for raw arrays.

They look pretty much similar on their public interfaces (even if their
internal implementation is quite different, but that should be pretty
inconsequential in most cases).

So, once again: Why exactly is std::vector the "correct" way to create
an array and std::deque the "wrong" way?

Due to their internal implementation there are situations where
std::vector is more suitable and efficient, while in other situations
std::deque is considerably better (either because of its additional
features, its efficiency in certain situations, or both). However,
as a pure array replacement they look pretty much the same.
std::vector is clearly designed as an array replacement.

As said, std::deque looks pretty much the same from the outside.
What stops it from being a good array replacement?
There's a reason no one starts teaching STL containers with std::deque.

And what would that reason be? Prejudice?
Realistically, the next thing he will wish to learn is how to read some
integer numbers from the command line, and at this point he already has
to unlearn everything he was taught about efficient fixed-size arrays.

Has to unlearn? That doesn't make any sense. You talk like a person
could only know either about fixed arrays or about std::vector, but not
both at the same time, and thus if he wants to learn about std::vector
he has to "unlearn" fixed arrays.

Obviously a person, even a beginner, can understand *both* constructs
at the same time. How about teaching both at the same time?
 
J

James Kanze

Christian Hackl <[email protected]> spake the secret code
<[email protected]> thusly:
std::vector<T> is a dynamic array.
Fixed-size arrays are perfectly fine in C++ and the syntax of
aggregate initialization from C is also perfectly fine.

Not to mention the fact that a C style array can have fully
static initialization, thus avoiding any order of initialization
problems.

Still, it's for special uses (most of mine are const); for
general work, std::vector is the choice, even if you're not
going to be adjusting the size once it has been constructed.
sizeof() is what you want to tell you the size of a fixed-size
array, i.e. sizeof(array_)/sizeof(array_[0])

For that, I use the template function size (which will cause
a compiler error, rather than a wrong value, if invoked on
a pointer.
 
Ad

Advertisements

J

James Kanze

Laurel Shimer <[email protected]>, on 23/08/2010 15:23:29, wrote:
<questions about managing raw arrays>
I wonder why nobody pointed out that we can simply wrap raw arrays into
a template in order to bring along their sizes, and we can do that quite
easily too.

You mean std::array, from C++0x (or tr1::array, before that).

Note that any solution involves compromizes. It's far from
trivial to come up with the "correct" solution. (In fact, one
should probably say *a* correct solution, since depending on
what you want, the correct solution might not be the same.)
It took me way more time to come up with the silly test case than to
write the actual wrapper:
//-------
// in some header or hidden in an implementation file
// with fitting explicit instantiations in an appropriate header
// (or maybe exported, if you're lucky)
// this can be, of course, widely extended and improved
template <class T, int SIZE> class Array {
public:
T& operator[](int index) {
return data[index];
}
const T& operator[](int index) const {
return data[index];
}
int size() const {
return SIZE;
}
private:
T data[SIZE];
};

This is interesting. You can't actually instantiate it unless
T has a default constructor, and all of the data are initialized
using the default constructor.

Probably the most important single reason for using a C style
array is the aggregate initialization sequence, and the fact
that it can have fully static initialization. (std::array
preserves this quality.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top