functio to load struct

  • Thread starter Bill Cunningham
  • Start date
B

Bill Cunningham

This is what I've been trying to accomplish. It compiles into an object
file with no complaints so there must be something right. I wanted a
function to load up a pointer to a struct.

#include "c.h"

struct cat *load(char *name, char *color)
{
struct cat *temp;
temp->color = color;
temp->name = name;
return temp;
}

Bill
 
S

Sjouke Burry

Bill said:
This is what I've been trying to accomplish. It compiles into an object
file with no complaints so there must be something right. I wanted a
function to load up a pointer to a struct.

#include "c.h"

struct cat *load(char *name, char *color)
{
struct cat *temp;
temp->color = color;
temp->name = name;
return temp;
}

Bill
???? A pointer returned which exists as automatic memory?
And which does not point anywhere?
It can die before you can use it, and points to a random place.
How about:
struct cat *load(char *name, char *color)
{
static struct cat temp;
temp.color = color;
temp.name = name;
return &temp;
}
Now temp stays alive, and you return a pointer to it.
and temp stays valid until you use the function "load" again.
 
B

Bill Cunningham

Sjouke said:
???? A pointer returned which exists as automatic memory?
And which does not point anywhere?
It can die before you can use it, and points to a random place.
How about:
struct cat *load(char *name, char *color)
{
static struct cat temp;
temp.color = color;
temp.name = name;
return &temp;
}
Now temp stays alive, and you return a pointer to it.
and temp stays valid until you use the function "load" again.

I got this from kandr2 §6. on structs. There were no pointers in the
code like I used. The code looked more like yours with members to the
struct. But it was return temp rather than &temp.

Bill
 
B

Bill Cunningham

Sjouke said:
???? A pointer returned which exists as automatic memory?
And which does not point anywhere?
It can die before you can use it, and points to a random place.
How about:
struct cat *load(char *name, char *color)
{
static struct cat temp;
temp.color = color;
temp.name = name;
return &temp;
}
Now temp stays alive, and you return a pointer to it.
and temp stays valid until you use the function "load" again.

Why the static within the function? Isn't struct cat temp local to the
function?

Bill
 
N

Nick Keighley

Sjouke Burry wrote:

not necessarily wrong.

that's the problem. A pointer is just the address of a piece of
memory. Like any other variable it has to be initialised. You need to
point the pointer at something. You could use malloc() or a static
(statics have there own problems though)
    I got this from kandr2 §6. on structs.

no you didn't. K&R may not be perfect but it doesn't make boo-boos
like this.
 
B

Bill Cunningham

Nick Keighley wrote:

[snip]
that's the problem. A pointer is just the address of a piece of
memory. Like any other variable it has to be initialised. You need to
point the pointer at something. You could use malloc() or a static
(statics have there own problems though)

So you are saying use malloc() rather than static? How would you use
malloc() in this case?

Bill
 
S

Sjouke Burry

Bill said:
I got this from kandr2 §6. on structs. There were no pointers in the
code like I used. The code looked more like yours with members to the
struct. But it was return temp rather than &temp.

Bill
struct cat *load( tells us you want to return a pointer,
temp is a structure, &temp is a pointer to that.
 
S

Sjouke Burry

Bill said:
Why the static within the function? Isn't struct cat temp local to the
function?

Bill
Yes, and you cant use a local variable outside the function.
The static keyword makes temp a permanent one, and allows a
pointer to it to be used outside the funtion "load".
 
N

Nobody

So you are saying use malloc() rather than static? How would you use
malloc() in this case?

I'd suggest making the caller perform the allocation, and passing the
pointer in, i.e.:

void load(struct cat *result, char *name, char *color)
{
result->color = color;
result->name = name;
}

Returning a pointer to a static variable is poor practice (it means that
the function isn't re-entrant, so can't be used in multi-threaded code,
signal handlers, etc). Using malloc() is inefficient.

Having the caller perform the allocation is more flexible, and allows for
arrays of structures.
 
B

Bill Cunningham

Nobody said:
I'd suggest making the caller perform the allocation, and passing the
pointer in, i.e.:

void load(struct cat *result, char *name, char *color)
{
result->color = color;
result->name = name;
}

Returning a pointer to a static variable is poor practice (it means
that the function isn't re-entrant, so can't be used in
multi-threaded code, signal handlers, etc). Using malloc() is
inefficient.

Having the caller perform the allocation is more flexible, and allows
for arrays of structures.

So the pointer result contains all the data that has been passed to the
2nd and 3rd parameters then right?

Bill
 
B

Bill Cunningham

Nobody wrote:

[...]
Returning a pointer to a static variable is poor practice (it means
that the function isn't re-entrant, so can't be used in
multi-threaded code, signal handlers, etc). Using malloc() is
inefficient.

Having the caller perform the allocation is more flexible, and allows
for arrays of structures.

What about having the source from this code declared static outside the
function and using one C source code page for this load function? Called
load.c and compiled to load.o and link. static struct cat temp in load.c
only. Wouldn't that cut out namespace pollution?

B
 
M

Moi

This is what I've been trying to accomplish. It compiles into an object
file with no complaints so there must be something right. I wanted a
function to load up a pointer to a struct.

#include "c.h"

struct cat *load(char *name, char *color) {
struct cat *temp;

This means: I have a variable, called temp, which is a pointer to "
struct cat". Currently it does not point anywhere, but it is
supposed to point at a "struct cat" (or be NULL)
temp->color = color;

Wait. temp does not point anywhere.
It is just a variable of type "pointer to struct cat",
which is not initialized or assigned, so it does not point anywhere.
Even worse: it can point to *anywhere*: maybe it points to garbage,
be NULL, or it can even ,accidently, point to a "struct dog" somewhere.
temp->name = name;
return temp;

You return a value of type "pointer to struct cat"
, which does not point anywhere.

HTH,
AvK
 
K

Keith Thompson

Bill Cunningham said:
This is what I've been trying to accomplish. It compiles into an object
file with no complaints so there must be something right.

This is a potentially dangerous attitude.

It's not nearly sufficient to have "something right". The goal is
to have *everything* right. A program that compiles without error
but doesn't execute correctly isn't significantly better than a
program that fails to compile.
I wanted a
function to load up a pointer to a struct.

Why? What is your goal?
#include "c.h"

struct cat *load(char *name, char *color)
{
struct cat *temp;
temp->color = color;
temp->name = name;
return temp;
}

Obtaining a pointer to an object that doesn't already exist can
be tricky. There are multiple approaches, each with its own
advantages and disadvantages.

You can return a pointer to a static object, which is straightforward
but means you only have one copy of the object in your entire
program.

You can require the caller to create the object (by whatever means)
and pass a pointer as an argument. This places an additional burden
on the caller.

You can have your function allocate the object with malloc.
This means the caller has to be responsible for deallocating it,
and both the caller and the function have to deal with allocation
failures.

You've chosen none of these alternatives. Your code will not work,
though it might accidentally appear to do so.

Note also that structs (unlike arrays) can be passed, returned, and
assigned by value:

struct cat new_cat(char *name, char *color)
{
struct cat result;
result.color = color;
result.name = name;
return result;
}

This has its own disadvantages. It doesn't give you a pointer, so
you'll have to modify the caller to handle a returned struct value.
It (probably) copies the entire structure, which could be inefficient
if the structure is very large.
 
N

Nobody

So the pointer result contains all the data that has been passed to
the
2nd and 3rd parameters then right?

You would use it like e.g.:

struct cat mycat;
...
load(&mycat, name, color);

After which, mycat will have been assigned.
 
N

Nobody

What about having the source from this code declared static outside the
function and using one C source code page for this load function? Called
load.c and compiled to load.o and link. static struct cat temp in load.c
only. Wouldn't that cut out namespace pollution?

Namespace pollution isn't the issue. It's a question of flexibility.

Having one function perform allocation and initialisation constrains you
to a particualar allocation mechanism. Having the caller pass in a pointer
allows separates initialisation from allocation, so you can initialise
static, automatic or dynamic variables, as well as elements of
arrays and structures,
 
B

Bill Cunningham

Moi said:
This means: I have a variable, called temp, which is a pointer to "
struct cat". Currently it does not point anywhere, but it is
supposed to point at a "struct cat" (or be NULL)

I see this now.
 
B

Bill Cunningham

Keith said:
Why? What is your goal?

[snip]

I'm not ignoring your question here. It's hard for me to find the words. I
want a linked list of cat data. Cat just as an example. It could be employee
records or what have you. I want to load the struct by a function. The
caller returning the pointer sounds like a good way and I haven't seen an
example using malloc() yet.

Bill
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top