structs

M

Matthew Jakeman

If i create a cruct like so :

struct test{
char *var1 ;
int var2 ;
short var3 ;
}

and i want to allocate it memory, should i allocate enough to hold the max
amount of data that will go into the char * plus the size of an int plus the
size of a short or do i need to allocate it more memory than this (the
reason i was wondering is i dont know how C handles structs in memory and
how it "binds" the variables together). If this is the case i presume then
allocating ps.var1 is not neccessary as using ps.var1 will use the memory
already allocated. Please point me in the right direction if I am not
getting this.

Cheers
Matt
 
M

Mike Wahler

Matthew Jakeman said:
If i create a cruct like so :

struct test{
char *var1 ;
int var2 ;
short var3 ;
}

Missing semicolon.

};
and i want to allocate it memory,

Allocate sizeof(struct test) bytes in order to
provide sufficient memory to store one instance
of type 'struct test'.
should i allocate enough to hold the max
amount of data that will go into the char *

'char *' is a type, whose size is sizeof(char*) bytes.
That's the maximum amount of 'data' that will 'go into' it.

If you want your 'char*' pointer to contain the address
of some other memory, allocate that much, and assign its
address to the pointer.

struct test x;
x.var1 = malloc(how_many_bytes);
plus the size of an int plus the
size of a short

No, don't include sizes of other members when allocating
memory for the pointer member to point to.
or do i need to allocate it more memory than this (the
reason i was wondering is i dont know how C handles structs in memory

Get some books! :)
See www.accu.org book reviews for recommendations.
and
how it "binds" the variables together).

The first member of a struct object always has the same
address as the struct object itself. The language allows
'padding' between members, and after the last. Thus the
'sizeof' a struct type can be, and often is, larger than
the sum of the sizes of its members.
If this is the case i presume then
allocating ps.var1 is not neccessary as using ps.var1 will use the memory
already allocated.

Although you didn't state it, I'll assume that 'ps' is an
object of type 'struct test' (it can't be a pointer, since
the '.' operator would not be valid to use with it):

struct test ps;

The size of 'ps' is at least the sum of the sizes of types
'char*', 'int', and 'short' (but may be larger). The 'char*'
type member occupies sizeof(char*) bytes. It's value (an
address) is meaninless until you assign it one.

#include <stdlib.h>

struct test
{
char *var1 ;
int var2 ;
short var3 ;
} = {0};

int main()
{
struct test ps; /* occupies sizeof(struct ps) bytes */
ps.var1 = malloc(100); /* 'ps.var1' contains address of allocated memory
*/
/* of at least 100 bytes */


struct test *ptr = malloc(sizeof *ptr);
/* 'ptr' contains address of allocated memory of */
/* at least sizeof(struct test) bytes */

if(ptr)
ptr->var1 = malloc(20); /* '(*ptr).var1' contains address of
allocated */
/* memory of at least 20 bytes */

/* clean up */
free(ps.var1);
free(ptr->var1);
free(ptr);

return 0;
}
Please point me in the right direction if I am not
getting this.

OK, I'm pointing you to C books. It would also help if you
describe exactly what problem you're trying to solve.

-Mike
 
E

Eric Sosman

Matthew said:
If i create a cruct like so :

struct test{
char *var1 ;
int var2 ;
short var3 ;
}

and i want to allocate it memory, should i allocate enough to hold the max
amount of data that will go into the char * plus the size of an int plus the
size of a short or do i need to allocate it more memory than this (the
reason i was wondering is i dont know how C handles structs in memory and
how it "binds" the variables together). If this is the case i presume then
allocating ps.var1 is not neccessary as using ps.var1 will use the memory
already allocated. Please point me in the right direction if I am not
getting this.

For an instance of the struct, you need to allocate
`sizeof(struct test)' bytes. Period.

If the `var1' element is to point somewhere, there
must be some memory allocated at that "somewhere." This
might be memory you obtain separately from malloc(), or
it might be a plain old variable, or it might be a string
literal, or ... `var1' is perfectly happy to point at
any chunk of memory you feel like. There is no necessary
"connection" between that memory and the memory for the
struct instance. Bad ASCII art:

struct:
var1 ----------> [elsewhere]
var2 = 42
var3 = 042

If `var1' is supposed to point to some memory that
is managed as "associated with" or "part of" the struct
instance, then you might want to allocate one large chunk
of memory to hold both the struct instance and the stuff
that `var1' points to. For example, assuming the "stuff"
is a zero-terminated string:

struct test *p;
p = malloc(sizeof(struct test) + strlen(string) + 1);
if (p != NULL) {
strcpy ((char*)(p + 1), string);
p->var1 = (char*)(p + 1);
p->var2 = 42;
p->var3 = 042;
}

More bad ASCII art:

struct:
var1 ---------+
var2 = 42 |
var3 = 042 |
string <----------+
copied
here
'\0'

HOWEVER, I do not recommend such shenanigans until your
grasp of C becomes a bit firmer than it appears to be now:
Learn to swim before you learn to dive, or you'll likely get
in over your head. Patience, Grasshopper, patience.
 
R

Russell Hanneken

Matthew said:
If i create a cruct like so :

struct test{
char *var1 ;
int var2 ;
short var3 ;
}

and i want to allocate it memory, should i allocate enough to hold the max
amount of data that will go into the char * plus the size of an int plus the
size of a short or do i need to allocate it more memory than this

You need to allocate memory both for the struct, and the buffer that you
want var1 to point at. For example:

struct test *ps = malloc ( sizeof *ps );
ps->var1 = malloc ( MAX_LENGTH + 1 );

Of course, you don't have to use malloc to allocate memory:

struct test s;
char buffer[MAX_LENGTH + 1] = "";
s.var1 = buffer;
 
M

Matthew Jakeman

Thanks for the help guys, when the bugger that has borrowed my C book has
the decency to give it back ill look it up in there as well!
Cheers
Matt

Eric Sosman said:
Matthew said:
If i create a cruct like so :

struct test{
char *var1 ;
int var2 ;
short var3 ;
}

and i want to allocate it memory, should i allocate enough to hold the max
amount of data that will go into the char * plus the size of an int plus the
size of a short or do i need to allocate it more memory than this (the
reason i was wondering is i dont know how C handles structs in memory and
how it "binds" the variables together). If this is the case i presume then
allocating ps.var1 is not neccessary as using ps.var1 will use the memory
already allocated. Please point me in the right direction if I am not
getting this.

For an instance of the struct, you need to allocate
`sizeof(struct test)' bytes. Period.

If the `var1' element is to point somewhere, there
must be some memory allocated at that "somewhere." This
might be memory you obtain separately from malloc(), or
it might be a plain old variable, or it might be a string
literal, or ... `var1' is perfectly happy to point at
any chunk of memory you feel like. There is no necessary
"connection" between that memory and the memory for the
struct instance. Bad ASCII art:

struct:
var1 ----------> [elsewhere]
var2 = 42
var3 = 042

If `var1' is supposed to point to some memory that
is managed as "associated with" or "part of" the struct
instance, then you might want to allocate one large chunk
of memory to hold both the struct instance and the stuff
that `var1' points to. For example, assuming the "stuff"
is a zero-terminated string:

struct test *p;
p = malloc(sizeof(struct test) + strlen(string) + 1);
if (p != NULL) {
strcpy ((char*)(p + 1), string);
p->var1 = (char*)(p + 1);
p->var2 = 42;
p->var3 = 042;
}

More bad ASCII art:

struct:
var1 ---------+
var2 = 42 |
var3 = 042 |
string <----------+
copied
here
'\0'

HOWEVER, I do not recommend such shenanigans until your
grasp of C becomes a bit firmer than it appears to be now:
Learn to swim before you learn to dive, or you'll likely get
in over your head. Patience, Grasshopper, patience.
 
G

Gordon Burditt

struct test{
char *var1 ;
int var2 ;
short var3 ;
}

and i want to allocate it memory,

Then allocate it sizeof(struct test) bytes of memory.
This does NOT include any memory for var1 to point at.
If you want memory for that, call malloc() AGAIN.
should i allocate enough to hold the max
amount of data that will go into the char * plus the size of an int plus the
size of a short or do i need to allocate it more memory than this (the
reason i was wondering is i dont know how C handles structs in memory and
how it "binds" the variables together).

I don't think the kind of "binding" you are thinking of exists.
If you want dynamic memory for var1 to point at, allocate it
(probably with a separate call to malloc(), but it could also
be in an auto array or a string literal, among other possibilities.
Pointers can point at things besides dynamically allocated memory).
If this is the case i presume then
allocating ps.var1 is not neccessary as using ps.var1 will use the memory
already allocated. Please point me in the right direction if I am not
getting this.

You need to assign a valid pointer value to ps.var1 that points somewhere,
before attempting to use it, and to get that valid pointer, you may
have to call malloc() again..

Please get your presumer fixed.

When it comes to dynamically allocated memory (and lots of other things
in C): You are responsible for DOING IT YOURSELF. You want memory
for a pointer to point at? Allocate it yourself. You want to free
it? free() it yourself. C won't do it for you. You want to have
enough memory to fit your string into? It's your problem to allocate
enough memory or make sure the string fits in existing allocated memory.
Failure to do this is how buffer overflow attacks work.

Gordon L. Burditt
 
M

Martin Ambuhl

Matthew said:
If i create a cruct like so :

struct test{
char *var1 ;
int var2 ;
short var3 ;
}

and i want to allocate it memory, ...

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

struct test
{
char *var1;
int var2;
short var3;
};

int main(void)
{
struct test *t; /* will point to a struct test */
struct test v = {.var1 = 0 }; /* is a struct test */
printf("The sizes reported below will vary by implementation.\n\n");

printf("The struct test v needs no allocation.\n"
"It has size %lu, and its members are:\n"
"v.var1 (a char *), with size %lu\n"
"v.var2 (an int), with size %lu\n"
"v.var3 (a short int), with size %lu\n\n",
(unsigned long) sizeof v,
(unsigned long) sizeof v.var1,
(unsigned long) sizeof v.var2,
(unsigned long) sizeof v.var3);
if (!(t = malloc(sizeof *t))) { /* attempt to allocate memory */
fprintf(stderr, "allocation for *t failed, quiting.\n");
exit(EXIT_FAILURE);
}
printf("The struct test pointer t has size %lu.\n"
"The space allocated for it to point to (*t) has size %lu\n"
"Its members are:\n"
"(*t).var1 (a char *), with size %lu\n"
"(*t).var2 (an int), with size %lu\n"
"(*t).var3 (a short int), with size %lu\n",
(unsigned long) sizeof t,
(unsigned long) sizeof *t,
(unsigned long) sizeof(*t).var1,
(unsigned long) sizeof(*t).var2,
(unsigned long) sizeof(*t).var3);

free(t); /* release allocated space */
return 0;
}
 

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,144
Messages
2,570,823
Members
47,369
Latest member
FTMZ

Latest Threads

Top