function

B

Bill Cunningham

I have been looking for a function from ANSI C that would start out with
a buffer size of zero initialized and would grow to a certain size. I have
already been able to set aside a 32 byte type using malloc(). Could calloc()
be what I'm looking for? This buffer would be able to grow by a mechanism
that would include using fscanf to find the size of a file in bytes. So my
question is simply is there any functions or ways in c89 to fill a buffer to
a certain size before it's clear? int buffer[] won't work unless it's a
char.

Bill
 
L

lolzy

    I have been looking for a function from ANSI C that would start out with
a buffer size of zero initialized and would grow to a certain size. I have
already been able to set aside a 32 byte type using malloc(). Could calloc()
be what I'm looking for? This buffer would be able to grow by a mechanism
that would include using fscanf to find the size of a file in bytes. So my
question is simply is there any functions or ways in c89 to fill a bufferto
a certain size before it's clear? int buffer[] won't work unless it's a
char.

Bill

I'm sorry, I can't understand you... could you explain exactly what
you want to achieve?
 
B

Ben Bacarisse

Bill Cunningham said:
I have been looking for a function from ANSI C that would start out with
a buffer size of zero initialized and would grow to a certain size. I have
already been able to set aside a 32 byte type using malloc(). Could calloc()
be what I'm looking for?
No.

This buffer would be able to grow by a mechanism
that would include using fscanf to find the size of a file in bytes. So my
question is simply is there any functions or ways in c89 to fill a buffer to
a certain size before it's clear?

Yes. There are "ways" in C89 to write almost any program -- it's a
general purpose language after all.

No standard function does what you want. Many programming languages can
do what you want in a single function call (or equivalent) but you seem
determined to butt your head up against, what is to you, C's impenetrable
syntax and library.
int buffer[] won't work unless it's a char.

What an odd statement! Fortunately I don't need to know what you mean
by it.
 
M

Mark Bluemel

On 11 aug, 11:04, "Bill Cunningham"<[email protected]> wrote:

[It really doesn't matter what he wrote]
I'm sorry, I can't understand you... could you explain exactly what
you want to achieve?

It seems unlikely. Bill's been around here spouting impenetrable
nonsense for quite some time, there's no indication that that will
change any time soon.

Some say that he is a troll, others that he has cognitive issues. (All I
know is he's not the Stig!)

Over the time I've been reading this newsgroup, there has been no sign
that Bill learns from any information given to him. Because of this,
many people have given up bothering with his posts.

I only see him in people's replies, as I have him kill-filed.
 
B

Bill Cunningham

Gordon said:
A buffer is not of size zero. C doesn't have zero-sized objects.
Even if it did, you can't initialize a zero-sized buffer without
overflowing it.


You can use realloc() to change the size of a malloc()ed buffer
(upwards or downwards). You can use memset() to clear, for example,
the newly-allocated part of the buffer (assuming the size grew).
Or, your code can fill in the appropriate values.

Ok. That may be what I'm looking for.
Beware that memset() is not appropriate to initialize struct elements
that are pointers or floating-point types (if that's what you are
going to put in the buffer) where all-bits-zero doesn't guarantee
a specific value. A NULL pointer is not guaranteed to be represented
as the bit pattern 0xdeadbeef even on machines where pointers are
32-bits.


By the time you have found out the size of a file in bytes, the size
of that file might have already changed. If you take one pass through
the file to calculate its size, allocate that much memory, and then
read the file again, you might end up overflowing the file or losing
the last part of it if it grows between passes.

Oh ok I see I didn't know that.
You can allocate an initial buffer, and keep growing the buffer
(usually *NOT* by one byte at a time; this is horribly inefficient)
with realloc() as needed until you've read the whole file. Some
people like doubling the size of the buffer each time. Then,
perhaps, you can shrink the buffer down to the actual size used.
The file still might grow while or after you finish reading it.


Filling a buffer does not change its size (unless you specifically
code a call to realloc() in this situation). Changing the size of
a buffer with realloc() does not "clear" it - the data in the minimum
size of the buffer before and after the realloc() is preserved.

This question does not make any sense. Please define the word
"clear" as you use it here.

I meant clear"ed". A typo. As in void free(void *)

I don't think that "filled with zero
bytes" nor "transparent; lacking color and colour" makes sense here.
Neither is the question "clear".
int buffer[] won't work unless it's a
char.

int buffer[] as a definition won't work even if <it> is a char,
regardless of what <it> refers to. You have to specify a (nonzero)
size.
 
R

Ralph Spitzner

Mark said:
On 08/11/2011 10:53 AM, (e-mail address removed) wrote: [whatever]


I only see him in people's replies, as I have him kill-filed.

He's looking for a 'self growing linked list storage',
which unfortunately is (to my knowledge) not a part
of _any_ programming language that I know of :p

-rasp
 
J

John Gordon

In said:
I have been looking for a function from ANSI C that would start out with
a buffer size of zero initialized and would grow to a certain size. I have

If you want a buffer that grows, malloc and realloc sound like a perfect
fit.
 
B

Ben Bacarisse

Ralph Spitzner said:
Mark said:
On 08/11/2011 10:53 AM, (e-mail address removed) wrote: [whatever]


I only see him in people's replies, as I have him kill-filed.

He's looking for a 'self growing linked list storage',
which unfortunately is (to my knowledge) not a part
of _any_ programming language that I know of :p

Haskel does. Bill wants to read a file, and Haskell's getContents is
just that. Because it's value is a lazy list, it will grow as needed
and, for that matter, it will also shrink as needed.
 
M

Malcolm McLean

    I have been looking for a function from ANSI C that would start out with
a buffer size of zero initialized and would grow to a certain size. I have
already been able to set aside a 32 byte type using malloc(). Could calloc()
be what I'm looking for? This buffer would be able to grow by a mechanism
that would include using fscanf to find the size of a file in bytes. So my
question is simply is there any functions or ways in c89 to fill a bufferto
a certain size before it's clear? int buffer[] won't work unless it's a
char.
You need realloc().

Start with a null pointer and a buffer of size zero. Then grow by a
bit each time. I usually use the formula new_size = (size_t) (oldsize
* 1.1 + 100). This means that the buffer grows by 10% each time, plus
a bit, so you don't have too many reallocations when it is small, and
you don't take up too much memory when it is large.

realloc() won't initialise data for you. You'll have to do that by
hand. There ought to be a recalloc() which zero-initialises data, but
there isn't.
 
B

Bill Cunningham

Malcolm said:
I have been looking for a function from ANSI C that would start out
with
a buffer size of zero initialized and would grow to a certain size.
I have already been able to set aside a 32 byte type using malloc().
Could calloc() be what I'm looking for? This buffer would be able to
grow by a mechanism that would include using fscanf to find the size
of a file in bytes. So my question is simply is there any functions
or ways in c89 to fill a buffer to a certain size before it's clear?
int buffer[] won't work unless it's a char.
You need realloc().

Start with a null pointer and a buffer of size zero. Then grow by a
bit each time. I usually use the formula new_size = (size_t) (oldsize
* 1.1 + 100). This means that the buffer grows by 10% each time, plus
a bit, so you don't have too many reallocations when it is small, and
you don't take up too much memory when it is large.

realloc() won't initialise data for you. You'll have to do that by
hand. There ought to be a recalloc() which zero-initialises data, but
there isn't.

Just what I need. Thanks very much.

Bill
 
B

Bill Cunningham

Ben said:
What an odd statement! Fortunately I don't need to know what you mean
by it.

Brain fart! As usual sometimes I don't know what I've talking about.

Bill
 
M

Malcolm McLean

why not 2x the buffer each time,
and realloc to actual size at end for the input?
it mess the malloc memory?
That's not too bad a strategy.

The problem is that if your buffer is very close to the system-imposed
limit, doubling may take it over that limit when in fact there are
enough resources to run your algorithm. Increasing by 10% is less
likely to do that.
 
B

Bill Cunningham

Malcolm said:
That's not too bad a strategy.

The problem is that if your buffer is very close to the system-imposed
limit, doubling may take it over that limit when in fact there are
enough resources to run your algorithm. Increasing by 10% is less
likely to do that.

Can you show me an example of code using malloc realloc and fread to use
this type of buffer?

Bill
 
M

Malcolm McLean

Malcolm McLean wrote:

    Can you show me an example of code using malloc realloc and freadto use
this type of buffer?

Bill

/*
read integers from a file
assume that int is 32 bit, and that endianness is native. End of
file = end of data
fp - open file
N - return for number of integers read
Out of memory: returns 0, N = -1;
IO error: returns 0, N = -2;

Note: untested code. Might have bugs in it.
*/
int *readintsfromfile(FILE *fp, int *N)
{
int *answer = 0;
int *temp;
int bufsize = 100;
int Nread = 0;
int x;

answer = malloc(bufsize * 4);
if(!answer)
goto outofmemory;
while(fread(&x, 4, 1, fp) == 1)
{
answer[Nread++] = x;
if(Nread == bufsize)
{
buffsize = bufsize + bufsize/10;
temp = realloc(answer, bufsize * 4);
if(!temp)
goto outofmemory;
answer = temp;
}
}
if(ferror(fp))
goto readerror;
*N = Nread;
return answer;
outofmeomory:
free(answer);
*N = -1;
return 0;
readerror:
free(answer);
*N = -2;
return 0;
}
 
N

Nobody

Use of 16-bit or 32-bit chars might also be appropriate if the native
character set is Unicode.

Not really. The question isn't the size of a "character", but the size of
the smallest "unit" of data which you wish to handle, as you can't have
any object smaller than a "char".

Which tends to mean that 16/32-bit "char" is reserved for highly
specialised architectures which don't need to deal with file formats,
network protocols, etc.
 
B

Bill Cunningham

Malcolm said:
/*
read integers from a file
assume that int is 32 bit, and that endianness is native. End of
file = end of data
fp - open file
N - return for number of integers read
Out of memory: returns 0, N = -1;
IO error: returns 0, N = -2;

Note: untested code. Might have bugs in it.
*/
int *readintsfromfile(FILE *fp, int *N)
{
int *answer = 0;
int *temp;
int bufsize = 100;
int Nread = 0;
int x;

answer = malloc(bufsize * 4);
if(!answer)
goto outofmemory;
while(fread(&x, 4, 1, fp) == 1)
{
answer[Nread++] = x;
if(Nread == bufsize)
{
buffsize = bufsize + bufsize/10;
temp = realloc(answer, bufsize * 4);
if(!temp)
goto outofmemory;
answer = temp;
}
}
if(ferror(fp))
goto readerror;
*N = Nread;
return answer;
outofmeomory:
free(answer);
*N = -1;
return 0;
readerror:
free(answer);
*N = -2;
return 0;
}

Excellent. Myself I might have used switch instead of goto or better yet
maybe confused myself with a string of if ,else if, and else statements. In
binary transfer would it be alright to use char* anyway? Transfer one byte
at 512, 1024 groups.

Bill
 
B

Ben Bacarisse

Bill Cunningham said:
Malcolm said:
/*
read integers from a file
assume that int is 32 bit, and that endianness is native. End of
file = end of data
fp - open file
N - return for number of integers read
Out of memory: returns 0, N = -1;
IO error: returns 0, N = -2;

Note: untested code. Might have bugs in it.
*/
int *readintsfromfile(FILE *fp, int *N)
{
int *answer = 0;
int *temp;
int bufsize = 100;
int Nread = 0;
int x;

answer = malloc(bufsize * 4);
if(!answer)
goto outofmemory;
while(fread(&x, 4, 1, fp) == 1)
{
answer[Nread++] = x;
if(Nread == bufsize)
{
buffsize = bufsize + bufsize/10;
temp = realloc(answer, bufsize * 4);
if(!temp)
goto outofmemory;
answer = temp;
}
}
if(ferror(fp))
goto readerror;
*N = Nread;
return answer;
outofmeomory:
free(answer);
*N = -1;
return 0;
readerror:
free(answer);
*N = -2;
return 0;
}

Excellent. Myself I might have used switch instead of goto [...]

How?

<snip>
 
B

Bill Cunningham

Bill said:
Malcolm said:
/*
read integers from a file
assume that int is 32 bit, and that endianness is native. End of
file = end of data
fp - open file
N - return for number of integers read
Out of memory: returns 0, N = -1;
IO error: returns 0, N = -2;

Note: untested code. Might have bugs in it.
*/
int *readintsfromfile(FILE *fp, int *N)
{
int *answer = 0;
int *temp;
int bufsize = 100;
int Nread = 0;
int x;

answer = malloc(bufsize * 4);
if(!answer)
goto outofmemory;
while(fread(&x, 4, 1, fp) == 1)
{
answer[Nread++] = x;
if(Nread == bufsize)
{
buffsize = bufsize + bufsize/10;
temp = realloc(answer, bufsize * 4);
if(!temp)
goto outofmemory;
answer = temp;
}
}
if(ferror(fp))
goto readerror;
*N = Nread;
return answer;
outofmeomory:
free(answer);
*N = -1;
return 0;
readerror:
free(answer);
*N = -2;
return 0;
}

Excellent. Myself I might have used switch instead of goto or
better yet maybe confused myself with a string of if ,else if, and
else statements. In binary transfer would it be alright to use char*
anyway? Transfer one byte at 512, 1024 groups.

Bill

Thing is. that's using a doubling and not 10%.

Bill
 
B

Bill Cunningham

Ben said:
Bill Cunningham said:
Malcolm said:
/*
read integers from a file
assume that int is 32 bit, and that endianness is native. End of
file = end of data
fp - open file
N - return for number of integers read
Out of memory: returns 0, N = -1;
IO error: returns 0, N = -2;

Note: untested code. Might have bugs in it.
*/
int *readintsfromfile(FILE *fp, int *N)
{
int *answer = 0;
int *temp;
int bufsize = 100;
int Nread = 0;
int x;

answer = malloc(bufsize * 4);
if(!answer)
goto outofmemory;
while(fread(&x, 4, 1, fp) == 1)
{
answer[Nread++] = x;
if(Nread == bufsize)
{
buffsize = bufsize + bufsize/10;
temp = realloc(answer, bufsize * 4);
if(!temp)
goto outofmemory;
answer = temp;
}
}
if(ferror(fp))
goto readerror;
*N = Nread;
return answer;
outofmeomory:
free(answer);
*N = -1;
return 0;
readerror:
free(answer);
*N = -2;
return 0;
}

Excellent. Myself I might have used switch instead of goto [...]

How?

<snip>

That would involve coding a different style and not leaving all the
labels for the end of the code and making things more confusing by having to
whack up code and end large chunks with break; constantly. As I said it
would probably look like a mess. Better left the way it is.

Bill
 
M

Malcolm McLean

    Excellent. Myself I might have used switch instead of goto or better yet
maybe confused myself with a string of if ,else if, and else statements. In
binary transfer would it be alright to use char* anyway? Transfer one byte
at 512, 1024 groups.
Yes. Normally it's easier to read binary data as unsigned chars using
fgetc(). However you can use fread.
 

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
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top