473,406 Members | 2,371 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Passing a pointer to pointer as a multi-dimensional array

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
4 6352
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


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
"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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Amr Mostafa | last post by:
Hello :) I'm trying to write a script that deals with a web service. I'm using NuSoap class. my question is : Can I pass some variables By Reference to the web service and get the result back...
3
by: Andy Read | last post by:
Dear all, I thought I understood passing parameters ByVal and ByRef but I clearly don't! If I define a simple class of: Public Class Person Public Name as String Public Age as Integer End...
6
by: Garma | last post by:
According to what I have learnt so far, instantiating global objects should be the last resort. Is there any reasons why so? Sometimes some objects or their pointers have to be shared among...
37
by: Ben | last post by:
Hi, there. Recently I was working on a problem where we want to save generic closures in a data structure (a vector). The closure should work for any data type and any method with pre-defined...
17
by: LP | last post by:
Hello, Here's the scenario: Object A opens a Sql Db connection to execute number of SqlCommands. Then it needs to pass this connection to a constructor of object B which in turn executes more...
12
by: Mike | last post by:
Consider the following code: """ struct person { char *name; int age; }; typedef struct person* StructType;
3
by: dice | last post by:
Hi, In order to use an external api call that requires a function pointer I am currently creating static wrappers to call my objects functions. I want to re-jig this so I only need 1 static...
6
by: Roman Mashak | last post by:
Hello, I belive the reason of problem is simple, but can't figure out. This is piece of code: struct timeval { long tv_sec; /* seconds */ long tv_usec; /* microseconds */ };
8
by: Ivan Liu | last post by:
Hi, I'd like to ask if passing an object as an pointer into a function evokes the copy constructor. Ivan
7
by: TS | last post by:
I was under the assumption that if you pass an object as a param to a method and inside that method this object is changed, the object will stay changed when returned from the method because the...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.