Groovy hepcat
no****@gmail.com was jivin' on 6 Sep 2006 03:26:45 -0700
in comp.lang.c.
2D array with different column types / Dumbass can figure out
segfault's a cool scene! Dig it!
>Okay ... Im out of practice. Is it not possible to have a 2D array
where each column is of a different type, say an int and a struct*? The
Well, you could use a union, I suppose. But it looks like what you
really need is a 1D array of struct. The first member of this struct
should be your int, and the second member your other struct. Something
like this:
#include <stdlib.h>
#define NUM 10
typedef struct
{
char* name;
int idx;
} A_Type;
struct allinfo
{
int foo;
A_Type bar;
};
int main(void)
{
struct allinfo a[NUM];
int i;
for(i = 0; i < NUM; i++)
{
a[i].foo = i;
a[i].bar.name = "My Name";
a[i].bar.idx = i;
}
return 0;
}
>following seg faults for me and I cant figure out what I need to
change.
Thanks.
#include <malloc.h>
No such header in standard C. What you need is this:
#include <stdlib.h>
>#include <string.h>
void*** a;
Why is this defined here, at file scope, instead of within a
function? There's no reason I can see to define this here. It would be
better defined in f().
>void f();
Prototypes have been around since 1989. And they're much better than
the alternative. There's no reason to use K&R style function
declarations anymore.
void f(void);
>typedef struct
{
char* name;
int idx;
} A_Type;
int main()
int main(void)
>{
f();
Why just have main() call f()? Seems rather pointless to me. It
would probably be better to put the guts of f() in main() instead. But
that's up to you.
You're not returning anything? You have an int function but you
don't return an int. That's not only not recommended, but actually
illegal in C90. Go on; return something. It's not hard.
return 0;
>}
void f()
void f(void)
>{
int i;
a = malloc(sizeof(void**) * 2);
a[0] = malloc(sizeof(int) * 10);
Wrong type. Since a is a void***, a[0] is a void**. *(a[0]) is,
therefore, a void*. But you are allocating enough space for 10 ints,
not 10 void*s.
a[1] = malloc(sizeof(A_Type*) * 10);
Wrong type. Since a is a void***, a[1] is a void**. *(a[1]) is,
therefore, a void*. But you are allocating enough space for 10
A_Type*s, not 10 void*s.
You have three malloc() calls here, none of which are checked for
failure. This is a very bad situation. malloc() can fail for unforseen
reasons; and when it does, you must take appropriate action to ensure
you don't dereference a null pointer.
Since the number of elements is known beforehand, why allocate
memory dynamically? An array would be better, I think.
A_Type* tmp;
for(i = 0; i < 10; i++)
{
tmp = malloc(sizeof(A_Type));
Another unchecked malloc() call. Bad!
tmp->name = "My Name";
tmp->idx = i;
memcpy(a[0][i], &i, sizeof(int)); /* SEG FAULT HERE */
a[1][i] = tmp;
}
}
Your use of void*** is flawed, I'm afraid. There are basically three
ways I can see around this: the way I have shown above, using another
struct; correcting what you are actually trying to do, using void* and
allocating a pointer to int or pointer to A_Type, as needed, and
assigning that to the void*; and using a union containing an int and
an A_Type, and simply using a 2D array of these. There may be other
ways I haven't thought of, but these should be enough. Of course, I
very much favour the first of those solutions. The other two are very
messy.
--
Dig the even newer still, yet more improved, sig!
http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?