By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,389 Members | 2,070 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,389 IT Pros & Developers. It's quick & easy.

Passing a pointer to pointer as a multi-dimensional array

P: n/a
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.

Jan 11 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
entitledX <li*********@hotmail.com> 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.
Jan 11 '06 #2

P: n/a


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).

--
Er*********@sun.com

Jan 11 '06 #3

P: n/a
"entitledX" <li*********@hotmail.com> 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) ks***@mib.org <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.
Jan 11 '06 #4

P: n/a
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.

Jan 12 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.