2x beginners questions

C

Chris Bradshaw

Hi group

I have been reading in my c book something about how C references
memory addresses but it's a little bit tricky.

so for example if I have

int num;

and the address of num is 100 then the compiler would treat that
variable internally as (int *)100 so
an address &num IS the same as (int *)100.

So the compiler treats the statement int num = 3; as *(int *)100 = 3
right?

But why do I need a pointer type and not for example (int)100 or
unsigned int(100)?

Second question: we are told in this book to "check the return value of
all memory and I/O functions and handle failure conditions gracefully",
one example given being f_close().

My quesiton is: apart from returning EOF -- where there is nothing the
programmer can do -- under what circumstances will fclose() fails?

Thanks
 
K

Keith Thompson

Chris Bradshaw said:
I have been reading in my c book something about how C references
memory addresses but it's a little bit tricky.

so for example if I have

int num;

and the address of num is 100 then the compiler would treat that
variable internally as (int *)100 so
an address &num IS the same as (int *)100.

It's actually best not to think of addresses as numbers. Address 100
might make sense on some particular system, but other systems might
represent addresses as, for example, a base+offset pair, or something
even more exotic.
So the compiler treats the statement int num = 3; as *(int *)100 = 3
right?

More or less, except that it also creates an object called "num"
(really a name for that location in memory).
But why do I need a pointer type and not for example (int)100 or
unsigned int(100)?

(int)100 is simply the int value 100. It's a number, not an address.
(And the cast is superfluous, since 100 is already of type int.)

But of course you don't need a pointer at all. You can just assign a
value to the object. (This works even if num happens to be stored in a
register and has no address.)
Second question: we are told in this book to "check the return value of
all memory and I/O functions and handle failure conditions gracefully",
one example given being f_close().

My quesiton is: apart from returning EOF -- where there is nothing the
programmer can do -- under what circumstances will fclose() fails?

Returning EOF is how fclose() indicates that it failed. It can do so
under several system-specific circumstances. For example, if some
pending output to a file has been buffered in memory, fclose() will
force it to be written to the physical file, which can fail if there's
insufficient space.

Depending on the circumstances, there are plenty of things the
programmer can do, starting with displaying an error message.
In some cases, it might also make sense to give the user an
opportunity to write the data somewhere else (think about saving
a file from a text editor).
 
B

Ben Bacarisse

Chris Bradshaw said:
I have been reading in my c book something about how C references
memory addresses but it's a little bit tricky.

It helps to know what book this is. For one thing, some people will be
able to follow along.
so for example if I have

int num;

and the address of num is 100 then the compiler would treat that
variable internally as (int *)100 so
an address &num IS the same as (int *)100.

So the compiler treats the statement int num = 3; as *(int *)100 = 3
right?

That's one way to start looking at these things, but it does not suit
every situation, so it may be a case of an author trying to be helpful
but missing the mark. I'd only stick with this view of things as far as
you find it helpful but bear in mind that it very often fails.

For example, the compiler may put a variable in a register or it may
simply not know the address to be used at the time the code is
generated. At some point (if you want a rounded education in this area)
you'll have to start considering these things.
But why do I need a pointer type and not for example (int)100 or
unsigned int(100)?

(int)100 means the same as 100 -- the cast of an integer constant to int
type does nothing. int(100) is a syntax error. If it is not treated as
one by your compiler then you are probably using C++ by accident.

What this means is that I can't answer your question. You must think
that (int)100 or int(100) mean something other than what they do mean so
unless I can guess what that is, I am stumped.

I prefer to think of variables as named boxes -- boxes whose content can
be changed by assignment. This is powerful metaphor that can be
extended to many more advanced areas of the language. The notion that
num can be thought of as *(int *)100 will soon run into trouble. It
already has for you since it relies on a concept that you are not yet
comfortable with -- pointers.

Unfortunately this is not much help if the only book you have uses this
very idea that has got you puzzled. Can you mix and match and read some
other book at the same time?
Second question: we are told in this book to "check the return value of
all memory and I/O functions and handle failure conditions gracefully",
one example given being f_close().

(you mean fclose())
My quesiton is: apart from returning EOF -- where there is nothing the
programmer can do -- under what circumstances will fclose() fails?

Just to clarify: EOF is not a circumstance under which fclose fails.
fclose signals every failure (no matter what the circumstances where) by
returning EOF.

The most common reason for an fclose failure is that there was data that
had not yet made it to the file when something went seriously wrong.
Imagine a hammer hitting the device the file is on, or unplugging the
network/USB device/power cord at the critical moment. There can be lots
of other problems, but the exact nature of them hardly matters.

Books often contain advice like this and it really helps if they tell
you what you might do. Critical data might be saved to some other
device, for example, or the user might be asked to plug in some other
storage device. The trouble is that all of these rely on a much deeper
knowledge of the system than most C books are prepared to rely on. The
best you can do in general is to report the failure to the user of your
program (if there is one).
 
N

Nobody

Second question: we are told in this book to "check the return value of
all memory and I/O functions and handle failure conditions gracefully",
one example given being f_close().

My quesiton is: apart from returning EOF -- where there is nothing the
programmer can do -- under what circumstances will fclose() fails?

If fclose() fails, the obvious thing to do is: *don't* treat the data as
having been "saved". If you're updating a file, don't delete the original.
If it's an interactive application, notify the user that the save
operation failed. If the program has a flag to indicate that the data has
been modified, don't clear it (so e.g. the user is prompted to save if
they try to quit). If the error occurred in the context of save-on-quit,
don't quit. And so on.

As for the case of malloc() failure, handling errors can be a bit more
complex. If you have completely run out of memory, failure tends to
become the norm. If you have a "cache" (i.e. data which can be
reconstructed, reloaded, etc), discarding it may release the memory you
need to recover. Otherwise, ensure that any error-recovery strategy
handles the out-of-memory situation correctly. In particular, if you
intend to save the program's data, don't overwrite existing files unless
you know that you can do so without needing to allocate memory. Losing the
most recent changes is an improvement over losing everything.
 

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

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top