469,081 Members | 1,701 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,081 developers. It's quick & easy.

Pointer to array of structs?

Still having a few problems with malloc and pointers.

I have made a struct. Now I would like to make a pointer an array with 4
pointers to this struct.

#include <stdlib.h>
#include <stdio.h>
typedef struct _tnode_t {
void *content;
struct _tnode_t *kids;
} tnode_t;
int main(void)
{
tnode_t *array;
array = malloc(sizeof(tnode_t)*4);
array[3] = NULL;
return 0;

}

As I understand "array" point to the first element of an array consisting of
space for 4 tnode_t structs. But why can't I initialize element at index 3
to NULL?
Feb 7 '06 #1
15 3213
Paminu wrote:
Still having a few problems with malloc and pointers.

I have made a struct. Now I would like to make a pointer an array with 4
pointers to this struct.

#include <stdlib.h>
#include <stdio.h>
typedef struct _tnode_t {
void *content;
struct _tnode_t *kids;
} tnode_t;
int main(void)
{
tnode_t *array;
array = malloc(sizeof(tnode_t)*4);
Better (and that may further illustrate the point below)

array = malloc(sizeof *array * 4);

showing you that you have allocated enough space to point to 4 of what
your variable `array' points to.
array[3] = NULL;
return 0;

}

As I understand "array" point to the first element of an array consisting of
space for 4 tnode_t structs. But why can't I initialize element at index 3
to NULL?


Because array[3] is a `tnode_t', not a pointer to a `tnode_t' -- and
NULL is a pointer constant.

If you want an array of *pointers* to tnode_t, you would write:

tnode_t **array = malloc(sizeof *array * 4);

and allocate enough space for a tnode_t for each element as needed.

HTH,
--ag
--
Artie Gold -- Austin, Texas
http://goldsays.blogspot.com
http://www.cafepress.com/goldsays
"If you have nothing to hide, you're not trying!"
Feb 7 '06 #2
Paminu wrote:
Still having a few problems with malloc and pointers.

I have made a struct. Now I would like to make a pointer an array with 4
pointers to this struct.

#include <stdlib.h>
#include <stdio.h>
typedef struct _tnode_t {
void *content;
struct _tnode_t *kids;
} tnode_t;
int main(void)
{
tnode_t *array;
array = malloc(sizeof(tnode_t)*4);
array[3] = NULL;
return 0;

}

As I understand "array" point to the first element of an array consisting of
space for 4 tnode_t structs. But why can't I initialize element at index 3
to NULL?


tnode_t *array; creates a pointer to a tnode_t structure. If you want
an array of 4 pointers to tnode_t structs you would use tnode_t
*array[4]. If you want want to create a dynamically allocated array of
pointers to tnode_t structures, you would want your pointer to be of
type "pointer to pointer to tnode_t":
tnode_t **array;

sizeof(tnode_t)*4 is the size required to store 4 tnode_t structures.
sizeof(tnode_t *)*4 will evaluate to the number of bytes required for 4
pointers to tnode_t.

Robert Gamble

Feb 7 '06 #3
Robert Gamble wrote:
Paminu wrote:
Still having a few problems with malloc and pointers.

I have made a struct. Now I would like to make a pointer an array with 4
pointers to this struct.

#include <stdlib.h>
#include <stdio.h>
typedef struct _tnode_t {
void *content;
struct _tnode_t *kids;
} tnode_t;
int main(void)
{
tnode_t *array;
array = malloc(sizeof(tnode_t)*4);
array[3] = NULL;
return 0;

}

As I understand "array" point to the first element of an array consisting
of space for 4 tnode_t structs. But why can't I initialize element at
index 3 to NULL?


tnode_t *array; creates a pointer to a tnode_t structure. If you want
an array of 4 pointers to tnode_t structs you would use tnode_t
*array[4].

It seems to work if I do:

int main(void)
{
tnode_t *array[4];
tnode_t *test;
test = malloc(sizeof(tnode_t));
test->content = "Test";
test->kids = NULL;

array[0] = test;
array[1] = NULL;
// etc.

printf("%s\n", array[0]->content);

return 0;

}
was that what you meant?
Feb 7 '06 #4
Robert Gamble wrote:
Paminu wrote:
Still having a few problems with malloc and pointers.

I have made a struct. Now I would like to make a pointer an array with 4
pointers to this struct.

#include <stdlib.h>
#include <stdio.h>
typedef struct _tnode_t {
void *content;
struct _tnode_t *kids;
} tnode_t;
int main(void)
{
tnode_t *array;
array = malloc(sizeof(tnode_t)*4);
array[3] = NULL;
return 0;

}

As I understand "array" point to the first element of an array consisting
of space for 4 tnode_t structs. But why can't I initialize element at
index 3 to NULL?


tnode_t *array; creates a pointer to a tnode_t structure.

Ok so it will only work if I set array[3] equal to a struct instead of a
pointer to a struct or NULL:

1)
tnode_t tt;
tt.content = "test";
tt.kids = NULL;
tnode_t *array;
array[0] = tt;
this seems to work and make sense. But if I make:

2)
int *p;
p = malloc(sizeof(int)*4);
p[0] = NULL;
this only give the warning: "warning: assignment makes integer from pointer
without a cast".

In 1) if I did: array[0] = NULL; I would get the error:

"error: incompatible types in assignment".

Why the different rules?

Feb 8 '06 #5
Paminu wrote:
Robert Gamble wrote:
Paminu wrote:
Still having a few problems with malloc and pointers.

I have made a struct. Now I would like to make a pointer an array with 4
pointers to this struct.

#include <stdlib.h>
#include <stdio.h>
typedef struct _tnode_t {
void *content;
struct _tnode_t *kids;
} tnode_t;
int main(void)
{
tnode_t *array;
array = malloc(sizeof(tnode_t)*4);
array[3] = NULL;
return 0;

}

As I understand "array" point to the first element of an array consisting
of space for 4 tnode_t structs. But why can't I initialize element at
index 3 to NULL?
tnode_t *array; creates a pointer to a tnode_t structure.

Ok so it will only work if I set array[3] equal to a struct instead of a
pointer to a struct or NULL:

1)
tnode_t tt;
tt.content = "test";
tt.kids = NULL;
tnode_t *array;
array[0] = tt;
this seems to work and make sense. But if I make:

2)
int *p;
p = malloc(sizeof(int)*4);
p[0] = NULL;
this only give the warning: "warning: assignment makes integer from pointer
without a cast".


You still seem to be confusing pointers to types with the types they
point. In the second code snippet you posted you declare a pointer to
integer and then allocate memory for four integers and assign the value
returned by malloc to your pointer. Now you have a dynamic array of
four integers that can be accessed as p[0], p[1], [2] and p[3] or any
equivalent way.

In your next statement you assign a null pointer constant (NULL) to
p[0]. This can be done and is perfectly legal, but it is implementation
defined. Pointers can be implicitly or explicitly converted to integers
and back in an implementation defined manner. The compiler is just
being nice telling you that this is something strange.

In 1) if I did: array[0] = NULL; I would get the error:

"error: incompatible types in assignment".

Why the different rules?


Here the scenario is totally different. array is of type pointer to
tnode_t. array[0] is of type tnode_t which is a struct. Now you're
trying to assign a null pointer constant to a struct and this cannot be
done. There's no implicit conversion between pointers and structs and
if you think of it for a while you'll realize that there is no such
conversion because it simply doesn't make sense.

HTH

Feb 8 '06 #6
Paminu wrote:
Still having a few problems with malloc and pointers.

I have made a struct. Now I would like to make a pointer an array with 4
pointers to this struct.

#include <stdlib.h>
#include <stdio.h>
typedef struct _tnode_t {
void *content;
struct _tnode_t *kids;
} tnode_t;
int main(void)
{
tnode_t *array;
array = malloc(sizeof(tnode_t)*4);
array[3] = NULL;
return 0;

}

As I understand "array" point to the first element of an array consisting of
space for 4 tnode_t structs. But why can't I initialize element at index 3
to NULL?


Because NULL is a pointer value. index 3 stores a tnode_t , not a
pointer to a tnode_t.

You cannot store a pointer in a place that cannot hold a pointer.

Feb 8 '06 #7

"Paminu" <sd**@asd.com> wrote in message
news:ds*********@news.net.uni-c.dk...
Robert Gamble wrote:
Paminu wrote:
Still having a few problems with malloc and pointers.

I have made a struct. Now I would like to make a pointer an array with 4 pointers to this struct.

#include <stdlib.h>
#include <stdio.h>
typedef struct _tnode_t {
void *content;
struct _tnode_t *kids;
} tnode_t;
int main(void)
{
tnode_t *array;
array = malloc(sizeof(tnode_t)*4);
array[3] = NULL;
return 0;

}

As I understand "array" point to the first element of an array consisting of space for 4 tnode_t structs. But why can't I initialize element at
index 3 to NULL?
tnode_t *array; creates a pointer to a tnode_t structure.

Ok so it will only work if I set array[3] equal to a struct instead of a
pointer to a struct or NULL:

1)
tnode_t tt;
tt.content = "test";
tt.kids = NULL;
tnode_t *array;
array[0] = tt;
this seems to work and make sense. But if I make:

2)
int *p;
p = malloc(sizeof(int)*4);
p[0] = NULL;
this only give the warning: "warning: assignment makes integer from

pointer without a cast".

In 1) if I did: array[0] = NULL; I would get the error:

"error: incompatible types in assignment".

Why the different rules?
Different errors.

The pointer to an int, p, can be assigned NULL:
p=NULL;

Or, you can assign the int that p[0] references to zero:
p[0]=0;

Or, you can assign the int that p[1] references to zero:
p[1]=0;

etc...

When you write: p[0] = NULL;

You are attempting to convert a pointer (NULL) to an int.
Rod Pemberton
Feb 8 '06 #8
"Nils O. Selåsdal" wrote:
Paminu wrote:
Still having a few problems with malloc and pointers.

I have made a struct. Now I would like to make a pointer an array with 4
pointers to this struct.

#include <stdlib.h>
#include <stdio.h>
typedef struct _tnode_t {
void *content;
struct _tnode_t *kids;
} tnode_t;
int main(void)
{
tnode_t *array;
array = malloc(sizeof(tnode_t)*4);
array[3] = NULL;
return 0;

}

As I understand "array" point to the first element of an array consisting
of space for 4 tnode_t structs. But why can't I initialize element at
index 3 to NULL?


Because NULL is a pointer value. index 3 stores a tnode_t , not a
pointer to a tnode_t.

You cannot store a pointer in a place that cannot hold a pointer.

Ok I guess that this is correct and identical:

typedef struct _tnode_t {
void *content;
struct _tnode_t *kids;
} tnode_t;

int main(void)
{
tnode_t *array;
array[0].kids = NULL;
array->kids = NULL;
return 0;

}

when I do this: array[i] I get a struct. When I do this: array->kids I get a
pointer to a struct.
Feb 9 '06 #9
Paminu wrote:

....snip...
Ok I guess that this is correct and identical:

typedef struct _tnode_t {
void *content;
struct _tnode_t *kids;
} tnode_t;

int main(void)
{
tnode_t *array;
array[0].kids = NULL;
array->kids = NULL;
return 0;

}

when I do this: array[i] I get a struct. When I do this: array->kids I get a
pointer to a struct.


There's still an issue, you've declared a pointer to a struct, but you
have not initialized it to a valid value (through a call to
malloc/calloc). Your program is dereferencing a pointer that doesn't
point to a valid block of memory and so invokes undefined behaviour.

Feb 9 '06 #10
On Wed, 08 Feb 2006 09:34:30 +0100, Paminu <sd**@asd.com> wrote:
Robert Gamble wrote:
Paminu wrote:
Still having a few problems with malloc and pointers.

I have made a struct. Now I would like to make a pointer an array with 4
pointers to this struct.

#include <stdlib.h>
#include <stdio.h>
typedef struct _tnode_t {
void *content;
struct _tnode_t *kids;
} tnode_t;
int main(void)
{
tnode_t *array;
array = malloc(sizeof(tnode_t)*4);
array[3] = NULL;
return 0;

}

As I understand "array" point to the first element of an array consisting
of space for 4 tnode_t structs. But why can't I initialize element at
index 3 to NULL?
tnode_t *array; creates a pointer to a tnode_t structure.

Ok so it will only work if I set array[3] equal to a struct instead of a
pointer to a struct or NULL:

1)
tnode_t tt;
tt.content = "test";
tt.kids = NULL;
tnode_t *array;
array[0] = tt;


tt is a tnode_t. array is a pointer to a tnode_t. array is not
initialized to point anywhere. array[0] would be the first tnode_t it
pointed if it did point anywhere. That is why your program is
syntactically correct. Some compilers warn you if you attempt to use
an uninitialized variable but even without the warning it is still
undefined behavior. If you added a call to malloc before using
array[0], array would then point to one or more structures and the
assignment would be fine.


this seems to work and make sense. But if I make:
Seeming to work is just leading down the path of murphy's law.
2)
int *p;
p = malloc(sizeof(int)*4);
p[0] = NULL;
this only give the warning: "warning: assignment makes integer from pointer
without a cast".
p is a pointer to int. p[0] is the first uninitialized int it points
to. NULL is not a suitable value for int. Hence the warning. Do not
think of it as "only". Your program is doing something much different
than you expect.

In 1) if I did: array[0] = NULL; I would get the error:

"error: incompatible types in assignment".
There is an implementation defined conversion from void* (the type of
NULL) to int. There is no such conversion from int* to struct.

Why the different rules?


Different types.
Remove del for email
Feb 10 '06 #11
Hi,
I have to say another problem that do not forget to free() them when
you allocated a pointer. Maybe there are no errors ,but that will cause
memory leak . ( Maybe your OS is stronger than mine :)

Feb 10 '06 #12
Ro*****@gmail.com wrote:
Hi,
I have to say another problem that do not forget to free() them when
you allocated a pointer. Maybe there are no errors ,but that will cause
memory leak . ( Maybe your OS is stronger than mine :)


What are you talking about? Who, or what are "them"? Etc...

Please quote what and who you're replying to. Read this:

"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>

--
BR, Vladimir

My OS can beat the hell out of yOurS.

Feb 10 '06 #13
Thanks for mentioning.
I am sorry about that, I am new here.
And I will pay attention to that.

Vladimir S. Oka wrote:
Ro*****@gmail.com wrote:
Hi,
I have to say another problem that do not forget to free() them when
you allocated a pointer. Maybe there are no errors ,but that will cause
memory leak . ( Maybe your OS is stronger than mine :)


What are you talking about? Who, or what are "them"? Etc...

Please quote what and who you're replying to. Read this:

"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>

--
BR, Vladimir

My OS can beat the hell out of yOurS.


Feb 10 '06 #14
Ro*****@gmail.com wrote:
Thanks for mentioning.
I am sorry about that, I am new here.
And I will pay attention to that.


Good, thank you. Also, don't top-post.

--
BR, Vladimir

43rd Law of Computing:
Anything that can go wr
fortune: Segmentation violation -- Core dumped

Feb 10 '06 #15
On Thu, 09 Feb 2006 08:18:53 +0100, Paminu <sd**@asd.com> wrote:
<snip>
Ok I guess that this is correct and identical:

typedef struct _tnode_t {
void *content;
struct _tnode_t *kids;
} tnode_t;
Most identifiers beginning with underscore are reserved to the
implementation and you shouldn't use them. This reservation is not
always enforced, indeed rarely is, but you are just asking for trouble
sometime in the future when it will be (maximally) incovenient. (There
are a few categories that are allowed, but your case here is not one
of them, and rather than remember the exact rules it's easier to avoid
all of them.)

Note it is perfectly legal to use the same identifier for the struct
tag and the typedef-name; they are in separate namespaces. If you
don't wish to, and do want to have both, the usual practice is to put
a suffix on one, either like typedef struct tnode { ... } tnode_t;
or like typedef struct tnode_s { ... } tnode;
int main(void)
{
tnode_t *array;
array[0].kids = NULL;
array->kids = NULL;
Yes. Given that the type is defined correctly (and as another reply
points out the pointer is initialized validly), then:
p -> e is defined as (*p) . e
p[0] is the same as *p
p[0] . e is the same as (*p) . e
return 0;

}

when I do this: array[i] I get a struct. When I do this: array->kids I get a
pointer to a struct.


But note that if array is actually an array, as the name implies,
array[i] allows you to access elements other than array[0], and
array[i].kids gives you the pointer in the i'th element. array->kids
gives you always and only array[0].kids.
- David.Thompson1 at worldnet.att.net
Feb 20 '06 #16

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by sathyashrayan | last post: by
10 posts views Thread by Kieran Simkin | last post: by
204 posts views Thread by Alexei A. Frounze | last post: by
13 posts views Thread by aegis | last post: by
7 posts views Thread by Ray Dillinger | last post: by
156 posts views Thread by Lame Duck | last post: by
14 posts views Thread by Szabolcs Borsanyi | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.