pointers


B

Bill Cunningham

Ok concering the first parameter of fread.

size_t fread(void *buf...,

The address seems to be passed to fread's first parameter a lot. Does it
have to be done that way? What I see is fread wanting a pointer to
something. And it doesn't have to be a char* because the generic pointer is
declared.

char *name="file";
fread(&name,

Why not
fread(name, or
fread(*name,

To dereference? *name points to the same address as returned by &name. Does
something about the first parameter scream out "Pass the address being
pointed too!" All I see is that void *buf wants a pointer.

Bill
 
Ad

Advertisements

L

Lew Pitcher

Ok concering the first parameter of fread.

size_t fread(void *buf...,

The address seems to be passed to fread's first parameter a lot. Does
it
have to be done that way? What I see is fread wanting a pointer to
something. And it doesn't have to be a char* because the generic pointer
is declared.

char *name="file";
fread(&name,
[snip]

Bill, you misunderstand what fread() uses that first parameter for.

The first parameter is /not/ the name of a file (as your example above
suggests). Instead, the parameter is a pointer to a buffer in which the
fread() function will place the data obtained from the file.

If fread() were only interested in obtaining character data, then that first
parameter /could have been/ defined as a char *.

But, fread() was intentionally designed to be able to read other forms of
data as well. With fread(), (by design) you /could/ read int values, or
float values, or even struct {} values. And, each read would need a buffer
of like type to store the results in.

An fread() of int values would need an int * buffer
An fread() of double values would need a double * buffer
An fread() of struct foo values would need a struct foo * buffer.

So, the first parameter to fread() is not only a pointer to a buffer, but it
must be a "typeless" pointer, to accomodate the alternative types that the
buffer may have.

Further, since fread() can read /multiple/ values, the buffer /may be/ an
array of the appropriate type.

In other words, fread()'s prototype must be able to cope with
FILE * raw_data_file;
struct foo { int bar; double baz; char blech[20]} foo_array[4];
fread(foo_array, sizeof foo_array[0], 4, raw_data_file);

as well as

FILE * character_data_file;
char buffer[256];
fread(buffer,1,256,character_data_file);


HTH
 
A

Andrew Poelstra

Ok concering the first parameter of fread.

size_t fread(void *buf...,

The address seems to be passed to fread's first parameter a lot. Does it
have to be done that way? What I see is fread wanting a pointer to
something. And it doesn't have to be a char* because the generic pointer is
declared.

char *name="file";
fread(&name,

&name is a pointer to a pointer to "file". But you want just a pointer
to "file". (Also, bear in mind that because you wrote "file" out as a
string constant, you can't legally read into it. Better to have written

char name[] = "file";

instead.)
Why not
fread(name, or

This one is what you want.
fread(*name,

*name is a char. Specifically, the char 'f'. It doesn't point to
anything, so fread can't use it.
To dereference? *name points to the same address as returned by &name. Does
something about the first parameter scream out "Pass the address being
pointed too!" All I see is that void *buf wants a pointer.

It wants a pointer to some memory that you're allowed to write
to. It will then write to said memory. That's all.


Andrew
 
B

Bill Cunningham

Bill, you misunderstand what fread() uses that first parameter for.

The first parameter is /not/ the name of a file (as your example above
suggests). Instead, the parameter is a pointer to a buffer in which the
fread() function will place the data obtained from the file.

If fread() were only interested in obtaining character data, then that
first
parameter /could have been/ defined as a char *.

But, fread() was intentionally designed to be able to read other forms of
data as well. With fread(), (by design) you /could/ read int values, or
float values, or even struct {} values. And, each read would need a buffer
of like type to store the results in.

An fread() of int values would need an int * buffer
An fread() of double values would need a double * buffer
An fread() of struct foo values would need a struct foo * buffer.

So, the first parameter to fread() is not only a pointer to a buffer, but
it
must be a "typeless" pointer, to accomodate the alternative types that the
buffer may have.

Further, since fread() can read /multiple/ values, the buffer /may be/ an
array of the appropriate type.

In other words, fread()'s prototype must be able to cope with
FILE * raw_data_file;
struct foo { int bar; double baz; char blech[20]} foo_array[4];
fread(foo_array, sizeof foo_array[0], 4, raw_data_file);

as well as

FILE * character_data_file;
char buffer[256];
fread(buffer,1,256,character_data_file);

So then in the above the buffer is created kind of as a work around for
what malloc() does it sound to me like. I seldom use fread. I prefer moving
things a bit or byte at a time so I focus more of getc and putc. I am
reading "Applied Cryptography" right now so in the future I might need to
work some with blocks of data so fread() may just be what I'm looking for.
I noticed above you didn't use fread(&buffer... so does that mean you
don't have to pass the address pointed to but the pointer itself in this
case the char array.
My question started with pointers and I guess I'm misunderstanding
fread() too.

Bill
 
K

Kleuskes & Moos

Bill, you misunderstand what fread() uses that first parameter for.
The first parameter is /not/ the name of a file (as your example above
suggests). Instead, the parameter is a pointer to a buffer in which the
fread() function will place the data obtained from the file.
If fread() were only interested in obtaining character data, then that
first
parameter /could have been/ defined as a char *.
But, fread() was intentionally designed to be able to read other forms of
data as well. With fread(), (by design) you /could/ read int values, or
float values, or even struct {} values. And, each read would need a buffer
of like type to store the results in.
An fread() of int values would need an int * buffer
An fread() of double values would need a double * buffer
An fread() of struct foo values would need a struct foo * buffer.
So, the first parameter to fread() is not only a pointer to a buffer, but
it
must be a "typeless" pointer, to accomodate the alternative types that the
buffer may have.
Further, since fread() can read /multiple/ values, the buffer /may be/ an
array of the appropriate type.
In other words, fread()'s prototype must be able to cope with
 FILE * raw_data_file;
 struct foo { int bar; double baz; char blech[20]} foo_array[4];
 fread(foo_array, sizeof foo_array[0], 4, raw_data_file);
as well as
 FILE * character_data_file;
 char buffer[256];
 fread(buffer,1,256,character_data_file);

    So then in the above the buffer is created kind of as a work around for
what malloc() does it sound to me like.

In some applications it is not convenient to "malloc/free" buffers
every time you read a block. You would rather malloc it once (or not
at all) and recycle the buffer. Hence the pointer.
I seldom use fread. I prefer moving things a bit or byte at a time so I focus more of getc and putc.

That may be called for in some apps. But in many/most cases the file
is buffered, and still reads a block at at time.
I am
reading "Applied Cryptography" right now so in the future I might need to
work some with blocks of data so fread() may just be what I'm looking for..
    I noticed above you didn't use fread(&buffer... so does that mean you
don't have to pass the address pointed to but the pointer itself in this
case the char array.
Yes.

    My question started with pointers and I guess I'm misunderstanding
fread() too.

:).
 
A

Andrew Poelstra

So then in the above the buffer is created kind of as a work around for
what malloc() does it sound to me like. I seldom use fread. I prefer moving

Well, it's putting the onus on /you/ to allocate the memory
before you call it. So it's kinda a workaround for malloc()
but you can still use malloc() if you want. You just have a
choice.

A common idiom is to use a local array:

char buffer[BLOCK_SIZE];
fread(buffer, 1, sizeof buffer, fh);

And that way you avoid potential memory allocation failures
and also likely save yourself a lot of CPU time because the
buffer will be in roughly the same area as your other local
data, which lets the CPU cache everything.
things a bit or byte at a time so I focus more of getc and putc. I am
reading "Applied Cryptography" right now so in the future I might need to
work some with blocks of data so fread() may just be what I'm looking for.

It's a tough book. Good luck.
And yes, fread() would be optimal for this purpose.
I noticed above you didn't use fread(&buffer... so does that mean you
don't have to pass the address pointed to but the pointer itself in this
case the char array.

The pointer /is/ the address pointed to. That's it's value.
You can think of it as an integer if you like, though often
that is not quite true. (DOS for example used funny segment
information that was crammed in there somehow.)

In any case, the pointer's value is what is passed. And that
value is the address pointed to.
My question started with pointers and I guess I'm misunderstanding
fread() too.

Only a little. You just need to make sure you know
what all the arguments you pass are supposed to be.


Andrew
 
Ad

Advertisements

S

Stefan Ram

Andrew Poelstra said:
A common idiom is to use a local array:
char buffer[BLOCK_SIZE];
fread(buffer, 1, sizeof buffer, fh);
And that way you avoid potential memory allocation failures

Allocating BLOCK_SIZE bytes with automatic storage duration
cannot fail?
 
B

Bill Cunningham

[snip]
&name is a pointer to a pointer to "file". But you want just a pointer
to "file". (Also, bear in mind that because you wrote "file" out as a
string constant, you can't legally read into it. Better to have written
So to use &name for example, The first parameter would look like
fread(void **buf...? I have seen the ampersand passed to this first
parameter before. And it seems always to be used as scanf()'s first
parameter. To me a void ** is a generic two dimensional array with an
unspecified number of elements. Possibly leading to overflow if one isn't
careful.

Reading parameters and knowing what they are asking for is something I
need to learn. I need to know when a parameter is calling for this:

char *name;
So just name,
*name, or
&name.

Bill
 
B

Barry Schwarz

snip


Only a little. You just need to make sure you know
what all the arguments you pass are supposed to be.

On the contrary. As his code amply demonstrates, his misunderstanding
is monumental.
 
A

Andrew Poelstra

[snip]
&name is a pointer to a pointer to "file". But you want just a pointer
to "file". (Also, bear in mind that because you wrote "file" out as a
string constant, you can't legally read into it. Better to have written
So to use &name for example, The first parameter would look like
fread(void **buf...? I have seen the ampersand passed to this first

Well, if you were reading into a variable - rather than a buffer - you
would need the & operator. Like, if you were reading an int value you
might have

int i;
fread(&i, 1, sizeof i, ...

But since a character buffer is /already/ a pointer to its data, there
is no need to use &.
parameter before. And it seems always to be used as scanf()'s first
parameter. To me a void ** is a generic two dimensional array with an

Nope, sorry. void* can be a "pointer to anything", but unfortunately void**
is a specific type - pointer to void*, and you lose a lot of the genericity
that void* gets you.
unspecified number of elements. Possibly leading to overflow if one isn't
careful.

Reading parameters and knowing what they are asking for is something I
need to learn. I need to know when a parameter is calling for this:

Google and your manpages (if you have them) will help you.
char *name;
So just name,
*name, or
&name.

name is a pointer to char.
*name is the char that name points to.
&name is a pointer to name.

Andrew
 
M

Michael Tsang

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Stefan said:
Andrew Poelstra said:
A common idiom is to use a local array:
char buffer[BLOCK_SIZE];
fread(buffer, 1, sizeof buffer, fh);
And that way you avoid potential memory allocation failures

Allocating BLOCK_SIZE bytes with automatic storage duration
cannot fail?

It can certainly fail. Even worse, once it fails, the program has no chance
to recover. However, when malloc() fails, it returns NULL and the program
can abort().
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAkt0GlMACgkQm4klUUKw07BDnwCcD8vd+Ewn6R8hg+e9CxJ5umli
RAYAn2A72v3Bc19zO9FdQ553ITL9d+YH
=Qcim
-----END PGP SIGNATURE-----
 
Ad

Advertisements

D

Default User

Lew said:
Ok concering the first parameter of fread.

size_t fread(void *buf...,

The address seems to be passed to fread's first parameter a
lot. Does it
have to be done that way? What I see is fread wanting a pointer to
something. And it doesn't have to be a char* because the generic
pointer is declared.

char *name="file";
fread(&name,
[snip]

Bill, you misunderstand what fread() uses that first parameter for.

Oddly, back a few years ago, he did know they were for:

<http://groups.google.com/group/comp.lang.c/browse_frm/thread/4b3be51aba
38d613>



In 2004, after another long thread about how to use fread(), Dan Pop
posted the following:


He's been posting idiotic questions in this newsgroup for over one year.
At this point, it is highly unrealistic to expect him to *ever* have a
better grasp on the language.


Nothing has changed since then, I'd say. He's either incapable of
learning, or trolling.



Brian
 
B

Bill Cunningham

Google and your manpages (if you have them) will help you.
My man pages were the first thing I looked at. Reading the parameters
didn't help and the man page was a little obscure. I don't have kandr2 with
me and my little C book didn't show any examples which didn't help much; I
have recently moved and haven't brought kandr2 yet. Since I don't use fread
I needed to remind myself what exactly the buf was for.
If one didn't want to use that first parameter what would you pass to it
? I might just try malloc.

Bill
 
T

Tom St Denis

    Ok concering the first parameter of fread.

size_t fread(void *buf...,

    The address seems to be passed to fread's first parameter a lot. Does it
have to be done that way? What I see is fread wanting a pointer  to
something. And it doesn't have to be a char* because the generic pointer is
declared.

    char *name="file";
    fread(&name,

Why not
fread(name, or
    fread(*name,

To dereference? *name points to the same address as returned by &name. Does
something about the first parameter scream out "Pass the address being
pointed too!" All I see is that void *buf wants a pointer.

In what way are you *not* a troll?

man fread
----------
NAME
fread, fwrite - binary stream input/output

SYNOPSIS
#include <stdio.h>

size_t fread(void *ptr, size_t size, size_t nmemb, FILE
*stream);

DESCRIPTION
The function fread() reads nmemb elements of data, each size
bytes long, from the stream pointed to by stream, storing them at the
location given by ptr.
 
S

Seebs

In what way are you *not* a troll?

One presumes that he *can't* read, at some fairly fundamental level.
Google "alexia" sometime and compare it to his posts.

-s
 
T

Tom St Denis

One presumes that he *can't* read, at some fairly fundamental level.
Google "alexia" sometime and compare it to his posts.

So if he has a reading comprehension problem the solution is an even
longer prose explanation? if he can't follow A=A, B=B, C=C then there
is no hope.

The real answer is he's either a troll or just unwilling to spend 3
seconds reading a man page [or both]. Since most of his posts are
about complete and fundamental misunderstanding of the basics of C I'd
think he's deliberately starting these threads to get attention.
Granted his tone isn't negative, he's still a waste of time.
 
Ad

Advertisements

A

Andrew Poelstra

My man pages were the first thing I looked at. Reading the parameters
didn't help and the man page was a little obscure. I don't have kandr2 with
me and my little C book didn't show any examples which didn't help much; I
have recently moved and haven't brought kandr2 yet. Since I don't use fread
I needed to remind myself what exactly the buf was for.

In fread(), like in fgets() and other functions, the buffer a
pointer to where the data that you read needs to go.
If one didn't want to use that first parameter what would you pass to it
? I might just try malloc.

You have to use the parameter. You have to give the data a
place to go.


Andrew
 
T

Tom St Denis

    My man pages were the first thing I looked at. Reading the parameters
didn't help and the man page was a little obscure. I don't have kandr2 with
me and my little C book didn't show any examples which didn't help much; I
have recently moved and haven't brought kandr2 yet. Since I don't use fread
I needed to remind myself what exactly the buf was for.
    If one didn't want to use that first parameter what would you pass to it
? I might just try malloc.

If you actually read the man page for 'fread' you'd see the first
parameter is NOT the file name.

However, since that's what you assumed we can only conclude you DID
NOT read the man page.
 
B

Bill Cunningham

If you actually read the man page for 'fread' you'd see the first
parameter is NOT the file name.

However, since that's what you assumed we can only conclude you DID
NOT read the man page.

The man page that I understood was

size_t fread (void* buf...etc.

void *buf tells me nothing except a pointer is wanted. It's been so long
since I've used fread. Well I understand now.

B
 
Ad

Advertisements

B

Bill Cunningham

man fread
----------
NAME
fread, fwrite - binary stream input/output

SYNOPSIS
#include <stdio.h>

size_t fread(void *ptr, size_t size, size_t nmemb, FILE
*stream);

DESCRIPTION
The function fread() reads nmemb elements of data, each size
bytes long, from the stream pointed to by stream, storing them at the
location given by ptr.

"Storing at the location given by ptr" ???? huh

Didn't remember that meant buffer. Sorry my C book says void * buf not the
man page.
 

Top