2D array of characters

Dear all,

I am having problems when doing serial HDF5 to read a 2D array of characters.

The writing of the array in hdf5_file works fine using basic HDF5 functions :
(...)
dimsfx[0] = FILE_LEN ;
dimsfx[1] = LINE_LEN ;
sprintf (buf_nameX,"%s,FileName);
dataset = H5LTmake_dataset(hdf5_file,buf_nameX,2,dimsfx,H5T_NATIVE_CHAR,buf_lig);
(...)

However I am having problems when reading this 2D-array from hdf5_file::
(...)
char **data;
data = (char**)malloc((FILE_LEN)*sizeof(char*));
         for (int i = 0; i < FILE_LEN; i++) {
               data[i] = (char*)malloc(LINE_LEN*sizeof(char));
        }

if(status = H5LTread_dataset_char(hdf5_file,DATASETNAME,*data) == NULL) {
                   for (i = 0; i < FILE_LEN; i++) {
                                      printf("%s\n",data[i]);
                    }
}
(...)

Looks like the dataset stored in the memory/buffer does not have the same
structure than the dataset stored in the hdf5_file.

Could you please shed light on that point ?

Thanks,

Barbara

Hi,

I am having problems when doing serial HDF5 to read a 2D array of characters.

The writing of the array in hdf5_file works fine using basic HDF5 functions :
(...)
dimsfx[0] = FILE_LEN ;
dimsfx[1] = LINE_LEN ;
sprintf (buf_nameX,"%s,FileName);
dataset = H5LTmake_dataset(hdf5_file,buf_nameX,2,dimsfx,H5T_NATIVE_CHAR,buf_lig);
(...)

However I am having problems when reading this 2D-array from hdf5_file::
(...)
char **data;
data = (char**)malloc((FILE_LEN)*sizeof(char*));
         for (int i = 0; i < FILE_LEN; i++) {
               data[i] = (char*)malloc(LINE_LEN*sizeof(char));
        }

This isn't a 2D array in the normal C/C++ sense - what you have
here is an array of FILE_LEN pointers to char *, and then each
element pointing to an array of FILE_LEN chars. That's quite a
different thing from a

char data[ FILE_LEN ][ FILE_LEN ];

While in the data structure you're using the 1D arrays of chars
can be allocated at more or less random places in memory, in the
second case (for the classic C 2D array) they are all are follo-
wing each other. And that's what the read function expects.

if(status = H5LTread_dataset_char(hdf5_file,DATASETNAME,*data) == NULL) {
                   for (i = 0; i < FILE_LEN; i++) {
                                      printf("%s\n",data[i]);

Probably the simplest fix is to change the way you allocate the
memory. If you change it to

char **data = malloc( FILE_LEN * sizeof *data );
char *tmp = malloc( FILE_LEN * FILE_LEN );
for ( int i = 0; i < FILE_LEN; i++ ) {
    data[ i ] = tmp + i * FILE_LEN;
}

Calling malloc() only once makes sure that all the memory is
continuous. But, of course, you then have to deallocate only
data[0] (and, of course, data) once when you're done with the
array since all memory was allocated also in a single call of
malloc() instead of FILE_LEN calls.

                              Regards, Jens

···

On Thu, Dec 09, 2010 at 05:06:13PM -0500, Collignon, Barbara C. wrote:
--
  \ Jens Thoms Toerring ________ jt@toerring.de
   \_______________________________ http://toerring.de

Thanks Jens , it works now :slight_smile:

Barbara

···

________________________________________
From: hdf-forum-bounces@hdfgroup.org [hdf-forum-bounces@hdfgroup.org] On Behalf Of Jens Thoms Toerring [jt@toerring.de]
Sent: Thursday, December 09, 2010 5:45 PM
To: HDF Users Discussion List
Subject: Re: [Hdf-forum] 2D array of characters

Hi,

On Thu, Dec 09, 2010 at 05:06:13PM -0500, Collignon, Barbara C. wrote:

I am having problems when doing serial HDF5 to read a 2D array of characters.

The writing of the array in hdf5_file works fine using basic HDF5 functions :
(...)
dimsfx[0] = FILE_LEN ;
dimsfx[1] = LINE_LEN ;
sprintf (buf_nameX,"%s,FileName);
dataset = H5LTmake_dataset(hdf5_file,buf_nameX,2,dimsfx,H5T_NATIVE_CHAR,buf_lig);
(...)

However I am having problems when reading this 2D-array from hdf5_file::
(...)
char **data;
data = (char**)malloc((FILE_LEN)*sizeof(char*));
         for (int i = 0; i < FILE_LEN; i++) {
               data[i] = (char*)malloc(LINE_LEN*sizeof(char));
        }

This isn't a 2D array in the normal C/C++ sense - what you have
here is an array of FILE_LEN pointers to char *, and then each
element pointing to an array of FILE_LEN chars. That's quite a
different thing from a

char data[ FILE_LEN ][ FILE_LEN ];

While in the data structure you're using the 1D arrays of chars
can be allocated at more or less random places in memory, in the
second case (for the classic C 2D array) they are all are follo-
wing each other. And that's what the read function expects.

if(status = H5LTread_dataset_char(hdf5_file,DATASETNAME,*data) == NULL) {
                   for (i = 0; i < FILE_LEN; i++) {
                                      printf("%s\n",data[i]);

Probably the simplest fix is to change the way you allocate the
memory. If you change it to

char **data = malloc( FILE_LEN * sizeof *data );
char *tmp = malloc( FILE_LEN * FILE_LEN );
for ( int i = 0; i < FILE_LEN; i++ ) {
    data[ i ] = tmp + i * FILE_LEN;
}

Calling malloc() only once makes sure that all the memory is
continuous. But, of course, you then have to deallocate only
data[0] (and, of course, data) once when you're done with the
array since all memory was allocated also in a single call of
malloc() instead of FILE_LEN calls.

                              Regards, Jens
--
  \ Jens Thoms Toerring ________ jt@toerring.de
   \_______________________________ http://toerring.de

_______________________________________________
Hdf-forum is for HDF software users discussion.
Hdf-forum@hdfgroup.org
http://mail.hdfgroup.org/mailman/listinfo/hdf-forum_hdfgroup.org