Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Passing a pointer to pointer as a multi-dimensional array

Reply
Thread Tools

Passing a pointer to pointer as a multi-dimensional array

 
 
entitledX
Guest
Posts: n/a
 
      01-11-2006
Hi, I'm trying to use the HDF library to read a few HDF files that I
need to process. The data in each file varies in rows, but the
columns remain constant. Because of that, I had dynamically allocated
a set of
pointer to pointers as my multi-dimensional arrays. Here is my code (i
have omitted checking calloc's return value to make this shorter):

int **filter;
filter = calloc( ylength, sizeof(int*) );
for( i = 0 ; i < ylength ; i++ )
filter[i] = calloc( xlength, sizeof(int*) );

The problem is that the function I have to use SDreaddata works fine if
I declare filter as an actual multi-dimensional array: int
filter[ylength][xlength]; However, I keep getting segmentation fault
errors.
SDreaddata is declared as:

intn SDreaddata
(int32 sdsid, int32 *start, int32 *stride, int32 *end, void *
data);

data is the parameter I am trying to pass filter to.
Is there a way of passing filter into this function, somehow? Thanks in
advance.

 
Reply With Quote
 
 
 
 
Christopher Benson-Manica
Guest
Posts: n/a
 
      01-11-2006
entitledX <(E-Mail Removed)> wrote:

> int **filter;
> filter = calloc( ylength, sizeof(int*) );
> for( i = 0 ; i < ylength ; i++ )
> filter[i] = calloc( xlength, sizeof(int*) );


That inner calloc call should be sizeof(int), or better sizeof(
*filter[i] ). The possible size difference between int and int* may
be part of your problem.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      01-11-2006


entitledX wrote On 01/11/06 11:58,:
> Hi, I'm trying to use the HDF library to read a few HDF files that I
> need to process. The data in each file varies in rows, but the
> columns remain constant. Because of that, I had dynamically allocated
> a set of
> pointer to pointers as my multi-dimensional arrays. Here is my code (i
> have omitted checking calloc's return value to make this shorter):
>
> int **filter;
> filter = calloc( ylength, sizeof(int*) );
> for( i = 0 ; i < ylength ; i++ )
> filter[i] = calloc( xlength, sizeof(int*) );
>
> The problem is that the function I have to use SDreaddata works fine if
> I declare filter as an actual multi-dimensional array: int
> filter[ylength][xlength]; However, I keep getting segmentation fault
> errors.
> SDreaddata is declared as:
>
> intn SDreaddata
> (int32 sdsid, int32 *start, int32 *stride, int32 *end, void *
> data);
>
> data is the parameter I am trying to pass filter to.
> Is there a way of passing filter into this function, somehow? Thanks in
> advance.


Study Questions 6.18 through 6.20 in the comp.lang.c
Frequently Asked Questions (FAQ) list at

http://c-faq.com/

.... and ask again if you're still perplexed. Arrays of
pointers (what you've created) are not the same as arrays
of arrays (which SDreaddata() appears to require).

--
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-11-2006
"entitledX" <(E-Mail Removed)> writes:
> Hi, I'm trying to use the HDF library to read a few HDF files that I
> need to process. The data in each file varies in rows, but the
> columns remain constant. Because of that, I had dynamically allocated
> a set of
> pointer to pointers as my multi-dimensional arrays. Here is my code (i
> have omitted checking calloc's return value to make this shorter):
>
> int **filter;
> filter = calloc( ylength, sizeof(int*) );
> for( i = 0 ; i < ylength ; i++ )
> filter[i] = calloc( xlength, sizeof(int*) );


Don't bother using calloc() for the first allocation. The differences
between calloc() and malloc() are that calloc() takes two arguments to
specify the size, and calloc() zeros the allocated space. For the
first, you can just use malloc() and do the multiplication yourself.
For the second, it doesn't do you any good here; all-bits-zero isn't
necessarily a useful value for an int* (it *might* be a null pointer,
but that's not guaranteed), and you re-assign values to all the
elements anyway.

The recommended form for the first allocation is:
filter = malloc(ylength * sizeof *filter);
or, if you prefer:
filter = malloc(ylength * sizeof(*filter));

Whether calloc() makes sense for the second allocation is another
question. All-bits-zero is guranteed to be a representation of 0 for
an integer type (the standard doesn't say so, but the committee has
ruled on it). And of course you want sizeof(int), not sizeof(int*).

> The problem is that the function I have to use SDreaddata works fine if
> I declare filter as an actual multi-dimensional array: int
> filter[ylength][xlength]; However, I keep getting segmentation fault
> errors.
> SDreaddata is declared as:
>
> intn SDreaddata
> (int32 sdsid, int32 *start, int32 *stride, int32 *end, void *
> data);
>
> data is the parameter I am trying to pass filter to.
> Is there a way of passing filter into this function, somehow? Thanks in
> advance.


You're creating an array of pointers to arrays of int. Each row is
allocated separately. The SDreaddata() function appears to expect a
pointer to a *contiguous* array of int32, which it treats as a
2-dimensional array. Since C doesn't support dynamically sized
2-dimensional arrays very well, you have to specify the stride (the
number of elements in each row).

I'm not certain of this, since we can't see what SDreaddata() actually
does with its parameters, but it certainly doesn't expect a
pointer-to-pointer-to-int.

Read section 6 of the C FAQ.

Also, you need to make sure the element type is consistent. You're
allocating arrays of int, but SDreaddata() uses int32 (that's not a
standard type; presumably it's a typedef for some 32-bit type). Type
int isn't necessarily 32 bits. If SDreaddata() expects int32, you
need to use int32 yourself.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Old Wolf
Guest
Posts: n/a
 
      01-12-2006
entitledX wrote:

> Hi, I'm trying to use the HDF library to read a few HDF files that I
> need to process. The data in each file varies in rows, but the
> columns remain constant. Because of that, I had dynamically
> allocated a set of pointer to pointers as my multi-dimensional
> arrays.


> intn SDreaddata (int32 sdsid,
> int32 *start, int32 *stride, int32 *end, void * data);
>
> data is the parameter I am trying to pass filter to.


Clearly, this function expects 'data' to be a contiguous bunch
of int32's. So you will have to allocate 'filter' in a contiguous
fashion.

(A pedantic point: the existing SDreaddata function will
cause undefined behaviour when it converts the (void *)
to (int *) because the value came from an int (*)[N]. But
this will work on any system I've ever heard of).

If your 'xlength' and 'ylength' variables are not known at
compile-time, then your only option is to allocate a 1-D
array for filter:

int32 *filter = calloc( xlength * ylength, sizeof *filter );

and then if you want to access it then you'll have to write
out your multiplications or use a macro, eg.

#define FILTER(X,Y) filter[(Y) * xlength + (X)]

However, if the number of columns is known at compiletime
(and if it is I suggest you use an upper-case identifier
for it), you can malloc a 2-D array:

int32 (*filter)[XLENGTH] = malloc( ylength * sizeof *filter );

and this array can be accessed as filter[x][y], and can
also be safely passed to SDreaddata(), with the same
pedantic caveat as I mentioned above.

If you have the option of modifying SDreaddata() to take
an (int *) instead of a (void *), then please do so. Then
pass *filter instead of filter in your version and in my
second version.

 
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
pointer to an array vs pointer to pointer subramanian100in@yahoo.com, India C Programming 5 09-23-2011 10:28 AM
Passing a 2D array as a pointer to a pointer PeterOut C Programming 3 08-28-2008 08:36 AM
passing the address of a pointer to a func that doesnt recieve a pointer-to-a-pointer jimjim C Programming 16 03-27-2006 11:03 PM
Re: Passing pointer to array from C to Python..and modifying same array in python? J W Python 0 07-14-2003 02:59 PM
Passing pointer to array from C to Python..and modifying same array in python? JW Python 1 07-12-2003 10:45 PM



Advertisments