return a string

N

Nascimento

Hello,

How to I do to return a string as a result of a function.
I wrote the following function:

char prt_tralha(int num)
{
int i;
char tralha[num];

tralha = "#";
for( i = 0; i < num-1; i++ )
strcpy(tralha, strcat(tralha,"#"));

return tralha;
}

And I really like to use it, thus:

int main()
{
printf("%s \n", prt_tralha(5));

return 0;
}

But when I compile it, gcc shows this message:

tmp.c: In function `prt_tralha':
tmp.c:16: error: incompatible types in assignment
tmp.c:20: warning: return makes integer from pointer without a cast
tmp.c:20: warning: function returns address of local variable

Thanks,

Nascimento
 
T

Thomas Matthews

Nascimento said:
Hello,

How to I do to return a string as a result of a function.
I wrote the following function:

char prt_tralha(int num)
{
int i;
char tralha[num];

tralha = "#";
for( i = 0; i < num-1; i++ )
strcpy(tralha, strcat(tralha,"#"));

return tralha;
}

And I really like to use it, thus:

int main()
{
printf("%s \n", prt_tralha(5));

return 0;
}

But when I compile it, gcc shows this message:

tmp.c: In function `prt_tralha':
tmp.c:16: error: incompatible types in assignment
tmp.c:20: warning: return makes integer from pointer without a cast
tmp.c:20: warning: function returns address of local variable

Thanks,

Nascimento

#include <stdio.h>
#include <stdlib.h>


const char * string_function(void)
{
static const char * my_text = "My text";
return my_text;
}

int main(void)
{
printf("%s\n", string_function());
return EXIT_SUCCESS;
}

Fundamentally, you pass a pointer to a string; not
the string.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
J

Jason

Nascimento said:
Hello,

How to I do to return a string as a result of a function.
I wrote the following function:

There are two ways to "return" a string from a function. One is to
simply return it...
char prt_tralha(int num)

I.E. char * ptr_tralha(int num)

Here we return a pointer to char, or string. The problem with this is
the return value can't be an automatic variable, so you'll need to work
with malloc.

Another method is to make the string part of the argument list. This is
probably prefered, since the memory management takes place outside of
the function and is (arguably) easier.

I.E. char ptr_tralha(int num, char *ret)
{
int i;
char tralha[num];

Assuming the later method, tralha would simply be the argument to this
function, and not declared here.
tralha = "#";
for( i = 0; i < num-1; i++ )
strcpy(tralha, strcat(tralha,"#"));

return tralha;

There would be no need to "return" tralha here, since it was passed in
via pointer in the argument list.
}

And I really like to use it, thus:

int main()
{
printf("%s \n", prt_tralha(5));

try this instead:

char tralha[5];
ptr_tralha(5,tralha);
printf("%s \n", tralha);
return 0;
}

But when I compile it, gcc shows this message:

tmp.c: In function `prt_tralha':
tmp.c:16: error: incompatible types in assignment

Well, of course. The function is (was) returning a char, but you were
trying to use it as if it were a char *.
tmp.c:20: warning: return makes integer from pointer without a cast
tmp.c:20: warning: function returns address of local variable

Thanks,

Hope this helps. I'm sure others will have suggestions as well.

-Jason
 
I

iru_muzgo

Nascimento,
you cannot assign a char to a string like that:
tralha = "#"
you can do it like this: tralha[0]='#';
A more elegant code for your purpose goes like this:

--- tralha.c ---

void
ptr_tralha(char *s)
{
while (*s != '\0') /* while the contents of s are different
* from NULL */
*s++ = '#'; /* s = '#' . increment s */
}


int
main(void)
{
char s[5];
ptr_tralha(s);
puts(s);

return 0;
}
 
J

Jason

Nascimento said:
int i;
char tralha[num];

tralha = "#";
for( i = 0; i < num-1; i++ )
strcpy(tralha, strcat(tralha,"#"));

Oh, no! Look what's happening here! You are trying to copy chars into
the tralha[] array without using the proper notation. This is bad.

What you want to do is use array substript notation or pointer
arithmetic. Substript is by far easier for the beginner.

tralha[0] = '#'; /* Use single quotes for char */
for( i = 1; i < num-1; i++ ) /* i=1, not 0 (see above) */
tralha = '#'; /* again, copy a char only */
tralha = '\0'; /* don't forget the terminator! */

You don't need (or want) strcpy or strcat when you are building an
array from scratch.
 
K

Keith Thompson

How to I do to return a string as a result of a function.
I wrote the following function:

char prt_tralha(int num)
{
int i;
char tralha[num];

tralha = "#";
for( i = 0; i < num-1; i++ )
strcpy(tralha, strcat(tralha,"#"));

return tralha;
}

And I really like to use it, thus:

int main()
{
printf("%s \n", prt_tralha(5));

return 0;
}

But when I compile it, gcc shows this message:

tmp.c: In function `prt_tralha':
tmp.c:16: error: incompatible types in assignment
tmp.c:20: warning: return makes integer from pointer without a cast
tmp.c:20: warning: function returns address of local variable

All three error messages are correct.

tralha = "#";
error: incompatible types in assignment

You can't assign strings like that. The name of a string variable (or
of any array) is implicitly converted, in most contexts, to a pointer
to its first element. See section 6 of the C FAQ,
<http://www.eskimo.com/~scs/C-faq/top.html>. You can initialize a
char array with a string literal, but I don't think that's what you
want in this case.

return tralha;
warning: return makes integer from pointer without a cast
warning: function returns address of local variable

You declared your function to return a char (a single character
value). You're trying to return a char*. The types are incompatible.
(The "integer" in the first warning refers to type char, which is an
integer type.)

Even if prt_tralha() were declared to return a char*, returning the
address of a local variable would be invalid. Your array tralha
ceases to exist as soon as the function terminates. Your main program
would receive a pointer to a non-existent object, and any attempt to
use it will invoke undefined behavior. In the worst case, it will
work as expected, failing only at the most inconvenient possible
moment. (The compiler isn't required to diagnose this error, but gcc
is kind enough to do so anyway.)

Other problems:

Your declaration "char tralha[num];" declares a variable length array
(VLA). This is a new feature in C99. If you're not concerned about
portability to compilers that don't support VLAs, that's fine, but you
should be aware that such support is not (yet?) universal. You might
consider using malloc() to allocate the memory dynamically.
for( i = 0; i < num-1; i++ )
strcpy(tralha, strcat(tralha,"#"));

What is the purpose of the strcpy()? strcat() appends "#" to your
string (assuming tralha is a valid string in the first place) and
returns a pointer to its first element. The strcpy() copies the
nstring onto itself. That's either undefined behavior or a no-op, I
don't remember which.

What you're trying to do is set tralha to a string of num '#'
characters. Using strcat() for this is wasteful.

for (i = 0; i < num; i ++) {
tralha = '#';
}
tralha[num] = '\0';

or

memset(tralha, '#', num);
tralha[num] = '\0';

And since you need space for the trailing '\0', the size of tralha had
better be at least num+1.

Since C doesn't treat arrays as first-class objects (you can't assign
them, compare them, or pass them as parameters, at least not
directly), dealing with character strings can be tricky, especially
when you don't know until execution time how big they're going to be.

If you want a function to return a variable-sized string (or any
array) to its caller, there are basically 3 ways to do it.

1. Let the caller allocate the array. The caller then needs to pass
in the address of the array and its size (and you need to decide what
to do if the caller's array isn't big enough). See the standard
fgets() function for an example.

2. Return a pointer to a static variable. Since static variables
continue to exist after the function returns, this avoids the problem
you had. The drawback is that there's only one allocated result; if
you call your function multiple times, each call will clobber the
previous result. This is especially bad in the presence of recursion
<OT>or multi-threading</OT>.

3. Allocate the result array in the function using malloc(). This is
probably the most flexible method, but it then require the caller to
free() the array when it's finished with it.
 
E

Eric Sosman

Nascimento said:
Hello,

How to I do to return a string as a result of a function.
I wrote the following function:

char prt_tralha(int num)
{
int i;
char tralha[num];

tralha = "#";
for( i = 0; i < num-1; i++ )
strcpy(tralha, strcat(tralha,"#"));

return tralha;
}

And I really like to use it, thus:

int main()
{
printf("%s \n", prt_tralha(5));

return 0;
}

But when I compile it, gcc shows this message:

tmp.c: In function `prt_tralha':
tmp.c:16: error: incompatible types in assignment
tmp.c:20: warning: return makes integer from pointer without a cast
tmp.c:20: warning: function returns address of local variable

You seem to be confused about several points. The
comp.lang.c Frequently Asked Questions (FAQ) list

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

covers some of them: Section 6 will help you understand
gcc's first complaint, Question 8.1 explains the second,
and Question 7.5 covers the third.

However, gcc did not catch all your errors. One that
it didn't catch is the strcpy() call: you are passing it
two strings that overlap, but strcpy() requires the source
and destination areas to be distinct. When you try to use
strcpy() on overlapping strings, anything at all might
happen. (Since the overlap is "perfect" -- the source and
destination are exactly the same string -- the strcpy()
call is pointless anyhow. I think this goes back to your
misunderstandings about strings; see FAQ section 8.)

Read the FAQ, re-read your textbook, and start over.
Good luck!
 
A

Alan Balmer

Hello,

How to I do to return a string as a result of a function.
I wrote the following function:

char prt_tralha(int num)

Here, you're saying to return a character, not a string. You want
char * prt_tralha(int num)
where the returned value will be a pointer to a character array
(string).
{
int i;
char tralha[num];

You can't declare a variable size array. What you can do is
char *tralha;
tralha = malloc(num);
but remember to check the return value to make sure the malloc
succeeded. One possibility is
if (tralha == NULL)
return NULL;


Also, since you are allocating new memory, it needs to be freed at
some point. More below on this.
tralha = "#";

You can't just assign strings. (Your first compiler error below.) You
can do
strcpy(tralha, "#");
for( i = 0; i < num-1; i++ )
strcpy(tralha, strcat(tralha,"#"));
This makes little sense, but I think I can guess what you're trying to
do. Make a string with num '#'s, right? How about
for( i = 0; i < num-1; i++ )
strcat(tralha, "#");
return tralha;

This is OK now, since you've allocated new memory for tralha. In your
original, you returned the address of a local array, which will be
invalid as soon as you return from the function. This is why you got
the third compiler error. The second error was because you were
returning a pointer, when you told the compiler you wanted to return a
char.
}

And I really like to use it, thus:

int main()
{
printf("%s \n", prt_tralha(5));

Now, we have the problem that prt_tralha has allocated memory which
needs to be freed. In your test program it doesn't matter, but in a
real program, every call to prt_tralha would allocate more memory, and
you could eventually run out. That's what we call a memory leak. One
way to fix this is

char *temp = prt_tralha(5);
if (temp != NULL)
{
printf("%s \n", temp);
free temp;
}
return 0;
}

But when I compile it, gcc shows this message:

Some hints: Look up the definitions and try to find example uses of
every library function you use, such as strcpy, strcat, malloc, free
above. I referred to all your compiler diagnostics as "errors" on
purpose. Unless you know exactly why the compiler issued a warning,
and you know for certain that it's harmless, consider it an error and
fix it. There is hardly ever a good reason for ignoring compiler
warnings.

Get a good tutorial. I recommend "The C Programming Language" by
Kernighan and Ritchie, which is a good tutorial and reference.
 
K

Keith Thompson

Nascimento,
you cannot assign a char to a string like that:
tralha = "#"
you can do it like this: tralha[0]='#';
A more elegant code for your purpose goes like this:

--- tralha.c ---

void
ptr_tralha(char *s)
{
while (*s != '\0') /* while the contents of s are different
* from NULL */

No. NULL is (a macro that expands to) a null *pointer* constant.
'\0' is a null character, sometimes referred to as NUL. Using the
term NULL to refer to a character value is misleading.
*s++ = '#'; /* s = '#' . increment s */
}


int
main(void)
{
char s[5];
ptr_tralha(s);
puts(s);

return 0;
}

Your array s is not initialized before you pass its address to
ptr_tralha(). Inside ptr_tralha(), you loop over the array until you
find a '\0' character, but there's no reason to assume that you ever
will. Unless there happens to be a '\0' character somewhere within s,
the loop in ptr_tralha() will go past the end of the array, invoking
undefined behavior.

I just tried compiling and running your program, and it printed a
string of 5 '#' characters followed by a newline. Apparently there
just happened to be no '\0' characters in s itself, but there just
happened to be a '\0' character immediately following it in memory.
This is just one of the infinitely many possible consequences of
undefined behavior.
 
K

Keith Thompson

Alan Balmer said:
On 29 Apr 2005 14:04:10 -0700, (e-mail address removed) (Nascimento)
wrote: [...]
{
int i;
char tralha[num];

You can't declare a variable size array.

Yes you can, if you have a C99 compiler or a pre-C99 compiler that
supports the feature. (The form of the diagnostics implies that he's
probably using gcc, which does support VLAs.)

I covered the portability issues in my previous followup.
 
E

Emmanuel Delahaye

Nascimento wrote on 29/04/05 :
How to I do to return a string as a result of a function.
I wrote the following function:

char prt_tralha(int num)
{
int i;
char tralha[num];

tralha = "#";

This is not going to happen. You can't change the value of an array
that way. You want strcpy().
for( i = 0; i < num-1; i++ )
strcpy(tralha, strcat(tralha,"#"));

Note that this is dangerous. The order of execution of the parameters
is defined by the implementation. BTW, chances are that strcat() is
called before strcpy(). Additionally, strcpy() only works with non
overlapping strings. Your construction doesn't guarantee that.

(To the gurus : [C99] shouldn't the 'restrict' keyword used here by the
compiler to generate some warning ?)

As a rule of thumb, don't use functions as a parameter to another
function. In mosts cases, it hurts...

Finally, it seems to be a very complicated way of filling a string...
return tralha;

Returning the address of a local variable is, in most cases, a
nonsense.
}

And I really like to use it, thus:

int main()
{
printf("%s \n", prt_tralha(5));

return 0;
}

But when I compile it, gcc shows this message:

tmp.c: In function `prt_tralha':
tmp.c:16: error: incompatible types in assignment

Ok, see above.
tmp.c:20: warning: return makes integer from pointer without a cast

Ok, I missed this one. Your function returns a char. You probably want
a char *.
tmp.c:20: warning: function returns address of local variable

A common newbie error. The fact is that the last warning *is* the
point. The address returned by a function must be valid after the
function has terminated. Keep in mind that the duration of the local
variables is limited to the bloc where it was defined. Meaning that
outside of the bloc, it doesn't longer exist. Hence, its address is no
longer valid. Returning its address is technically possible (say for
debug purpose), but dereferencing it out of the function invokes an
undefined behaviour.

There are 3 ways to correct your code.

- The worst : qualifying the array of char with 'static'. This
deceiving solution looks simple and easy, but it can generate other
more subtle bugs preventing from using the function in some cases
(nested calls, mutual calls, recursion, preemptive threads etc.)

- Passing the address of an array. The caller is the game master. He
defines the array, and ask the function to act on it through (address,
size) parameters. (see fgets() for example)

- The function is allocating the array. The caller gives enough
information so that the function is able to compute the requested size
for the array. That done, it allocates the array (malloc()), process
it, and returns its address. The duration of the allocated bloc is
under the control of the program. It ends with an appropriate free().

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Clearly your code does not meet the original spec."
"You are sentenced to 30 lashes with a wet noodle."
-- Jerry Coffin in a.l.c.c++
 
E

Emmanuel Delahaye

iru_muzgo wrote on 29/04/05 :
void
ptr_tralha(char *s)
{
while (*s != '\0') /* while the contents of s are different
* from NULL */

NULL is off-topic here. You meant 0. The probel, is what makes you
think that there is a 0 in the area pointed by s ? And even if ther is
one, what makes you think that it is at the right position ?

This is a serious design problem...
*s++ = '#'; /* s = '#' . increment s */
}

int
main(void)
{
char s[5];

As you can see, the contain of is undetermined.
ptr_tralha(s);

hence, the behaviour is undefined. Anything could happen...
puts(s);
return 0;
}

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Mal nommer les choses c'est ajouter du malheur au
monde." -- Albert Camus.
 
E

Emmanuel Delahaye

(supersedes <[email protected]>)

iru_muzgo wrote on 29/04/05 :
void
ptr_tralha(char *s)
{
while (*s != '\0') /* while the contents of s are different
* from NULL */

NULL is off-topic here. You meant 0. The probem is, what makes you
think that there is a 0 in the area pointed by s ? And even if there is
one, what makes you think that it is at the correct position ?

This is a serious design problem...
*s++ = '#'; /* s = '#' . increment s */
}

int
main(void)
{
char s[5];

As you can see, the contain of is undetermined.
ptr_tralha(s);

hence, the behaviour is undefined. Anything could happen...
puts(s);
return 0;
}

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Clearly your code does not meet the original spec."
"You are sentenced to 30 lashes with a wet noodle."
-- Jerry Coffin in a.l.c.c++
 
K

Keith Thompson

Emmanuel Delahaye said:
Nascimento wrote on 29/04/05 : [...]
for( i = 0; i < num-1; i++ )
strcpy(tralha, strcat(tralha,"#"));

Note that this is dangerous. The order of execution of the parameters
is defined by the implementation. BTW, chances are that strcat() is
called before strcpy().

Actually, I think it's guaranteed that strcat() will be called before
strcpy(). The order of evaluation of the arguments is unspecified,
but the function can't be called until all its arguments have been
evaluated; there's a sequence point between the evaluation of the
arguments and the actual call. It's bad code, but not for that
reason.
Additionally, strcpy() only works with non
overlapping strings. Your construction doesn't guarantee that.

In fact, it guarantees that the strings do overlap.

[...]
As a rule of thumb, don't use functions as a parameter to another
function. In mosts cases, it hurts...

I don't agree. It can be dangerous if you're dealing with pointers to
the same chunk of memory, but there's nothing wrong with using
function results as arguments in general.

printf("Length of string is %d\n", (int)strlen(s));
 
D

Daniel Haude

On 29 Apr 2005 14:04:10 -0700,
Nascimento said:
Hello,

How to I do to return a string as a result of a function.

All the answers you ever needed were already given. Here's a summary
(which I only post to reflect ,y own knowledge on the subject matter --
this is an invitation to the gurus to tear it apart).

1. Declare a static array of char in your function and return it (as the
asctime() function does). Simple but very limited.
Problem: printf("%s %s\n", foo(a), foo(b)); prints the same thing twice.

2. malloc() memory for the string inside your function and return pointer
to it. Simple but ugly because you have to remember to free the memory
later. Problem: printf("%s\n", foo(a)); is a memory leak. Also if the
function is tucked away in some library you have to make an effort to
provide a way to use an alternative allocation function.

3. Pass an already allocated buffer and its size to your function. Most
flexible but awkward, especially if all you want is to print some quantity
in a special format. Problem: Function must check buffer overflow and
signal error when buffer is too small.

All three methods have their respective drawbacks, so you must select the
one best suited to your purpose.

--Daniel
 
A

Alan Balmer

Alan Balmer said:
On 29 Apr 2005 14:04:10 -0700, (e-mail address removed) (Nascimento)
wrote: [...]
{
int i;
char tralha[num];

You can't declare a variable size array.

Yes you can, if you have a C99 compiler or a pre-C99 compiler that
supports the feature. (The form of the diagnostics implies that he's
probably using gcc, which does support VLAs.)
Quite right. I've been in C89 mode too long (since somewhat before
1989 :)
 
K

Keith Thompson

Daniel Haude said:
On 29 Apr 2005 14:04:10 -0700,


All the answers you ever needed were already given. Here's a summary
(which I only post to reflect ,y own knowledge on the subject matter --
this is an invitation to the gurus to tear it apart).

Good answers, but I have a couple of quibbles.
1. Declare a static array of char in your function and return it (as the
asctime() function does). Simple but very limited.
Problem: printf("%s %s\n", foo(a), foo(b)); prints the same thing twice.

I've used a variant of this. I had a function returning char* that
declared two local static variables, an array of arrays of char (for
the results), and an index. On each call, it would cycle the index
through the array and use a fresh sub-array for the result. This
allowed, say, half a dozen distinct calls to be active simultaneously.
It's not pretty, and it still forces you to decide in advance both how
big the result can be and how many distinct results you need, but it's
a bit more flexible than using a single static array.
2. malloc() memory for the string inside your function and return pointer
to it. Simple but ugly because you have to remember to free the memory
later. Problem: printf("%s\n", foo(a)); is a memory leak. Also if the
function is tucked away in some library you have to make an effort to
provide a way to use an alternative allocation function.

Why does tucking it away in some library imply that you need to
support an alternative allocation function? There may be (or may not)
an issue for functions that are part of the standard library <OT>and
but in most cases said:
3. Pass an already allocated buffer and its size to your function. Most
flexible but awkward, especially if all you want is to print some quantity
in a special format. Problem: Function must check buffer overflow and
signal error when buffer is too small.

Actually, it seems to me that #2 is the most flexible technique. It
allows the function itself to determine exactly how much memory it
needs, and imposes minimal complexity on the call (apart from the need
to free the allocated memory).
All three methods have their respective drawbacks, so you must select the
one best suited to your purpose.

Yes.
 
P

pete

Keith said:
Good answers, but I have a couple of quibbles.


I've used a variant of this. I had a function returning char* that
declared two local static variables, an array of arrays of char (for
the results), and an index. On each call, it would cycle the index
through the array and use a fresh sub-array for the result. This
allowed, say, half a dozen distinct calls to be active simultaneously.
It's not pretty, and it still forces you to decide in advance both how
big the result can be and how many distinct results you need, but it's
a bit more flexible than using a single static array.


Why does tucking it away in some library imply that you need to
support an alternative allocation function? There may be (or may not)
an issue for functions that are part of the standard library <OT>and


Actually, it seems to me that #2 is the most flexible technique. It
allows the function itself to determine exactly how much memory it
needs, and imposes minimal complexity on the call (apart from the need
to free the allocated memory).

I'm partial to number 3.
Actually the called function doesn't have to do any checking or
signaling as long the programmer considers the onus to
be on the calling function to supply a buffer large enough.
With number 3 you can use any kind of object,
automatic, static or allocated.
If an allocated object is used, then it is allocated and freed
in the same function, which is good.

#include <limits.h>
#include <stddef.h>
#include <stdio.h>

#define E_TYPE unsigned char
#define P_TYPE unsigned
#define STRING " %s = 0x%x\n"
#define INITIAL 0
#define FINAL 0xf
#define OFFSET (sizeof(e_type) * CHAR_BIT - 4)
#define INC(E) (++(E))

typedef E_TYPE e_type;
typedef P_TYPE p_type;

void bitstr(char *str, const void *obj, size_t n);

int main(void)
{
e_type e;
char ebits[CHAR_BIT * sizeof e + 1];

puts("\n/* BEGIN output from bitstr.c */\n");
for (e = INITIAL; FINAL >= e; INC(e)) {
bitstr(ebits, &e, sizeof e);
printf(STRING, OFFSET + ebits, (p_type)e);
}
puts("\n/* END output from bitstr.c */");
return 0;
}

void bitstr(char *str, const void *obj, size_t n)
{
unsigned mask;
const unsigned char *byte = obj;

while (n-- != 0) {
mask = ((unsigned char)-1 >> 1) + 1;
do {
*str++ = (char)(mask & byte[n] ? '1' : '0');
mask >>= 1;
} while (mask != 0);
}
*str = '\0';
}
 
C

CBFalconer

Keith said:
.... snip ...

I've used a variant of this. I had a function returning char* that
declared two local static variables, an array of arrays of char (for
the results), and an index. On each call, it would cycle the index
through the array and use a fresh sub-array for the result. This
allowed, say, half a dozen distinct calls to be active simultaneously.
It's not pretty, and it still forces you to decide in advance both how
big the result can be and how many distinct results you need, but it's
a bit more flexible than using a single static array.

I have used a system that looked roughly like this:

#define BUFSIZE 20
#define NBUFS 9 /* or whatever */

struct abuf {struct abuf *next; char buf[BUFSIZE]};

static struct abuf *initbuffs(void)
{
struct abuf *nxt, *first;
int i;

first = nxt = malloc(sizeof *nxt); /* No error testing */
first->buf = "";
for (i = NBUFS; i; i--) {
nxt->next = malloc(sizeof *(nxt->next));
nxt->buf = "";
}
return (nxt->next = first); /* forming ring buffer */
} /* initbuffs */

/* ------------------- */

char *getbuf(void)
{
static struct abuf *curbuff;

if (!curbuff) curbuff = initbuffs();
curbuff = curbuff->next;
return curbuff->buf;
} /* getbuf */

which does all its allocating on the very first call. Nothing
outside this code need know how it is built.
 

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,164
Messages
2,570,901
Members
47,439
Latest member
elif2sghost

Latest Threads

Top