Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > 2D array with different column types / Dumbass can figure out segfault

Reply
Thread Tools

2D array with different column types / Dumbass can figure out segfault

 
 
nobrow@gmail.com
Guest
Posts: n/a
 
      09-06-2006
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
following seg faults for me and I cant figure out what I need to
change.

Thanks.

#include <malloc.h>
#include <string.h>

void*** a;
void f();
typedef struct
{
char* name;
int idx;
} A_Type;

int main()
{
f();
}

void f()
{
int i;
a = malloc(sizeof(void**) * 2);
a[0] = malloc(sizeof(int) * 10);
a[1] = malloc(sizeof(A_Type*) * 10);

A_Type* tmp;
for(i = 0; i < 10; i++)
{
tmp = malloc(sizeof(A_Type));
tmp->name = "My Name";
tmp->idx = i;

memcpy(a[0][i], &i, sizeof(int)); /* SEG FAULT HERE */
a[1][i] = tmp;
}
}

 
Reply With Quote
 
 
 
 
nobrow@gmail.com
Guest
Posts: n/a
 
      09-06-2006

Konstantin Miller wrote:
> http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
>
> > 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
> > following seg faults for me and I cant figure out what I need to
> > change.
> >
> > Thanks.
> >
> > #include <malloc.h>
> > #include <string.h>
> >

> //void*** a;
> void **a;
> > void f();
> > typedef struct
> > {
> > char* name;
> > int idx;
> > } A_Type;
> >
> > int main()
> > {
> > f();
> > }
> >
> > void f()
> > {
> > int i;

> //a = malloc(sizeof(void**) * 2);
> a = malloc(sizeof(void*) * 2);
> > a[0] = malloc(sizeof(int) * 10);
> > a[1] = malloc(sizeof(A_Type*) * 10);
> >
> > A_Type* tmp;
> > for(i = 0; i < 10; i++)
> > {
> > tmp = malloc(sizeof(A_Type));
> > tmp->name = "My Name";
> > tmp->idx = i;
> >

> // memcpy(a[0][i], &i, sizeof(int)); /* SEG FAULT HERE */
> // you could do
> // memcpy(&(a[0][i]), &i, sizeof(int));
> // but why not simply:
> a[0][i] = i;
> > a[1][i] = tmp;
> > }
> > }

>
> Konstantin


Hi,

Thanks but as reasonable as that looks, its not working:

test.c:34: warning: dereferencing 'void *' pointer
test.c:34: error: invalid use of void expression
test.c:35: warning: dereferencing 'void *' pointer
test.c:35: error: invalid use of void expression

Lines 34 and 35 being:

a[0][i] = i;
a[1][i] = tmp;

 
Reply With Quote
 
 
 
 
Philip Potter
Guest
Posts: n/a
 
      09-06-2006
<(E-Mail Removed)> wrote in message
news:(E-Mail Removed) ups.com...
> 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
> following seg faults for me and I cant figure out what I need to
> change.
>
> Thanks.


It is possible but ugly, difficult, and error-prone. What are you trying to
do?

#define NUMINTS 5
#define NUMDBLS 10

void ** a;
a = malloc (2 * sizeof *a);
a[0] = malloc (NUMINTS * sizeof (int));
a[1] = malloc (NUMDBLS * sizeof (double));

// now, to set an int:
((int *)a[0])[3] = 42;

// and to set a double:
((double *)a[1])[6] = 3.141592;

The reason is that a's type is pointer-to-pointer-to-<something>. You can't
give it a concrete type since it's different in different columns. But you
can't dereference a pointer-to-<something> without knowing what the
<something> is. So, at some point in the expression you have to cast the
pointer to a concrete pointer type in order to dereference it.

If you have a fixed list of types, and you want an array for each type, why
don't you do just that?

int *a = malloc (NUMINTS * sizeof *a);
double *b = malloc (NUMDBLS * sizeof *b);

Or, alternatively, you could declare a struct:

struct mystruct {
int *iarray;
double *darray;
};

struct mystuct a;
a.iarray = malloc (NUMINTS * sizeof *a.iarray);
a.darray = malloc (NUMINTS * sizeof *a.darray);

Philip

 
Reply With Quote
 
nobrow@gmail.com
Guest
Posts: n/a
 
      09-06-2006

Konstantin Miller wrote:
> (E-Mail Removed) wrote:
>
> >
> > Konstantin Miller wrote:
> >> (E-Mail Removed) wrote:
> >>
> >> > 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
> >> > following seg faults for me and I cant figure out what I need to
> >> > change.
> >> >
> >> > Thanks.
> >> >
> >> > #include <malloc.h>
> >> > #include <string.h>
> >> >
> >> //void*** a;
> >> void **a;
> >> > void f();
> >> > typedef struct
> >> > {
> >> > char* name;
> >> > int idx;
> >> > } A_Type;
> >> >
> >> > int main()
> >> > {
> >> > f();
> >> > }
> >> >
> >> > void f()
> >> > {
> >> > int i;
> >> //a = malloc(sizeof(void**) * 2);
> >> a = malloc(sizeof(void*) * 2);
> >> > a[0] = malloc(sizeof(int) * 10);
> >> > a[1] = malloc(sizeof(A_Type*) * 10);
> >> >
> >> > A_Type* tmp;
> >> > for(i = 0; i < 10; i++)
> >> > {
> >> > tmp = malloc(sizeof(A_Type));
> >> > tmp->name = "My Name";
> >> > tmp->idx = i;
> >> >
> >> // memcpy(a[0][i], &i, sizeof(int)); /* SEG FAULT HERE */
> >> // you could do
> >> // memcpy(&(a[0][i]), &i, sizeof(int));
> >> // but why not simply:
> >> a[0][i] = i;
> >> > a[1][i] = tmp;
> >> > }
> >> > }
> >>
> >> Konstantin

> >
> > Hi,
> >
> > Thanks but as reasonable as that looks, its not working:
> >
> > test.c:34: warning: dereferencing 'void *' pointer
> > test.c:34: error: invalid use of void expression
> > test.c:35: warning: dereferencing 'void *' pointer
> > test.c:35: error: invalid use of void expression
> >
> > Lines 34 and 35 being:
> >
> > a[0][i] = i;
> > a[1][i] = tmp;

>
> Hi!
>
> That's right, you can not dereference a void pointer!
> Change those lines to
>
> ((int*)a[0])[i] = i;
> ((A_Type**)a[1])[i] = tmp;
>
> This must work!
>
> Konstantin


Lovely stuff. Thanks for your patience and your help.

 
Reply With Quote
 
Konstantin Miller
Guest
Posts: n/a
 
      09-06-2006
(E-Mail Removed) wrote:

> 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
> following seg faults for me and I cant figure out what I need to
> change.
>
> Thanks.
>
> #include <malloc.h>
> #include <string.h>
>

//void*** a;
void **a;
> void f();
> typedef struct
> {
> char* name;
> int idx;
> } A_Type;
>
> int main()
> {
> f();
> }
>
> void f()
> {
> int i;

//a = malloc(sizeof(void**) * 2);
a = malloc(sizeof(void*) * 2);
> a[0] = malloc(sizeof(int) * 10);
> a[1] = malloc(sizeof(A_Type*) * 10);
>
> A_Type* tmp;
> for(i = 0; i < 10; i++)
> {
> tmp = malloc(sizeof(A_Type));
> tmp->name = "My Name";
> tmp->idx = i;
>
> memcpy(a[0][i], &i, sizeof(int)); /* SEG FAULT HERE */
> a[1][i] = tmp;
> }
> }


Konstantin
 
Reply With Quote
 
Konstantin Miller
Guest
Posts: n/a
 
      09-06-2006
(E-Mail Removed) wrote:

> 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
> following seg faults for me and I cant figure out what I need to
> change.
>
> Thanks.
>
> #include <malloc.h>
> #include <string.h>
>

//void*** a;
void **a;
> void f();
> typedef struct
> {
> char* name;
> int idx;
> } A_Type;
>
> int main()
> {
> f();
> }
>
> void f()
> {
> int i;

//a = malloc(sizeof(void**) * 2);
a = malloc(sizeof(void*) * 2);
> a[0] = malloc(sizeof(int) * 10);
> a[1] = malloc(sizeof(A_Type*) * 10);
>
> A_Type* tmp;
> for(i = 0; i < 10; i++)
> {
> tmp = malloc(sizeof(A_Type));
> tmp->name = "My Name";
> tmp->idx = i;
>

// memcpy(a[0][i], &i, sizeof(int)); /* SEG FAULT HERE */
// you could do
// memcpy(&(a[0][i]), &i, sizeof(int));
// but why not simply:
a[0][i] = i;
> a[1][i] = tmp;
> }
> }


Konstantin
 
Reply With Quote
 
Konstantin Miller
Guest
Posts: n/a
 
      09-06-2006
(E-Mail Removed) wrote:

>
> Konstantin Miller wrote:
>> (E-Mail Removed) wrote:
>>
>> > 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
>> > following seg faults for me and I cant figure out what I need to
>> > change.
>> >
>> > Thanks.
>> >
>> > #include <malloc.h>
>> > #include <string.h>
>> >

>> //void*** a;
>> void **a;
>> > void f();
>> > typedef struct
>> > {
>> > char* name;
>> > int idx;
>> > } A_Type;
>> >
>> > int main()
>> > {
>> > f();
>> > }
>> >
>> > void f()
>> > {
>> > int i;

>> //a = malloc(sizeof(void**) * 2);
>> a = malloc(sizeof(void*) * 2);
>> > a[0] = malloc(sizeof(int) * 10);
>> > a[1] = malloc(sizeof(A_Type*) * 10);
>> >
>> > A_Type* tmp;
>> > for(i = 0; i < 10; i++)
>> > {
>> > tmp = malloc(sizeof(A_Type));
>> > tmp->name = "My Name";
>> > tmp->idx = i;
>> >

>> // memcpy(a[0][i], &i, sizeof(int)); /* SEG FAULT HERE */
>> // you could do
>> // memcpy(&(a[0][i]), &i, sizeof(int));
>> // but why not simply:
>> a[0][i] = i;
>> > a[1][i] = tmp;
>> > }
>> > }

>>
>> Konstantin

>
> Hi,
>
> Thanks but as reasonable as that looks, its not working:
>
> test.c:34: warning: dereferencing 'void *' pointer
> test.c:34: error: invalid use of void expression
> test.c:35: warning: dereferencing 'void *' pointer
> test.c:35: error: invalid use of void expression
>
> Lines 34 and 35 being:
>
> a[0][i] = i;
> a[1][i] = tmp;


Hi!

That's right, you can not dereference a void pointer!
Change those lines to

((int*)a[0])[i] = i;
((A_Type**)a[1])[i] = tmp;

This must work!

Konstantin
 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      09-07-2006
On 6 Sep 2006 03:26:45 -0700, (E-Mail Removed) wrote:

>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
>following seg faults for me and I cant figure out what I need to
>change.


snip code

It would be much simpler if you did it with an array of struct. Each
element of the array would be a row while each member of the struct
would be a column. You could have as many columns as you want, each
with an independent type.


Remove del for email
 
Reply With Quote
 
Peter Shaggy Haywood
Guest
Posts: n/a
 
      09-10-2006
Groovy hepcat (E-Mail Removed) 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"?
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
invoking a segfault within a segfault handler - is this undefinedbehavior? Andrey Vul C Programming 8 07-30-2010 02:14 PM
[ANN] ParseTree 3.0.1 Released (the "I'm a tired dumbass" release) Ryan Davis Ruby 0 10-23-2008 05:35 AM
Dumbass pinchee Computer Support 1 08-12-2006 11:15 PM
Here's a dumbass question James D Carroll Java 9 06-21-2004 07:32 PM
Another Dumbass Question: Table not found Child ASP .Net 3 08-08-2003 10:41 AM



Advertisments