Modified the example program vlstra.c

All,

My aim is to write an array of strings ( created dynamically into a
dataset (1D dataset ). I have a variable char ** strings defined .
Before writing this array is populated as given below .

Based on length strings = new char*[length];

Fill each strings[i] .

The dataset consists of a compound datatype wherein one of the
components is a variable length string array .

type = H5Tcopy (H5T_C_S1);

ret = H5Tset_size (type, H5T_VARIABLE);

//One of the components of the datatype is - comType has other
components as well

H5Tinsert(comType,"var str",0,type);

H5Dwrite writes all the strings to the given file as below in hdf5 file
( output from h5dump )

"\320\310\362\0138\312\362\013\350\312\362\013\230\314\362\013\370\314\3
62\013H\315\362\013\375\375\375\375\253\253\253\253\253\253\253\253\356\
376\356\376"

The number of strings written were 6. I stored 6 also a a separate value
in the dataset

When reading the length is read first and memory allocated as

  strings = new char*[length];

Then H5Dread is used to read in the value from hdf5 file . I get only
junk values and not the one that is written .

I also tried to modify one of the existing examples . But no success .

#ifdef __cplusplus

extern "C" {

#endif

#include "stdafx.h"

#include "..\..\hdf5\hdf5\hdf5-1.6.5_PC\src\hdf5.h"

//C:\HDF5\hdf5\hdf5\hdf5-1.6.5_PC\src

#include <stdlib.h>

#include <stdio.h>

#include <memory.h>

#define VFILE "vlstra.h5"

#define VRANK 1

#define VDIM 4

static void write_vlstr_attr ()

{

    hid_t file, root, dataspace, att;

    hid_t type;

    herr_t ret;

    hsize_t dims[]={1};

    const char *string_att[VDIM] = {"string1",

                                    "string2",

                                    "string3",

                                    "string4", };

   char **str;

    file = H5Fcreate(VFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

   // printf ("H5Fcreate returns: %i\n", file);

    /* Create a datatype to refer to. */

    type = H5Tcopy (H5T_C_S1);

   // printf ("H5Tcopy returns: %i\n", type);

    ret = H5Tset_size (type, H5T_VARIABLE);

   // printf ("H5Tset_size returns: %i\n", ret);

   hid_t strType = H5Tcreate(H5T_COMPOUND,sizeof(str));

   H5Tinsert(strType,"var str",0,type);

    root = H5Gopen(file, "/");

   // printf ("H5Gopen returns: %i\n", root);

    dataspace = H5Screate_simple(VRANK, dims, NULL);

   // printf ("H5Screate returns: %i\n", dataspace);

   str = new char*[4];

   for(int j=0;j<4 ; j++)

   {

         str[j] = new char[8];

         strcpy(str[j],string_att[j]);

   }

    att = H5Dcreate(root, "VarStrAtt", strType, dataspace, H5P_DEFAULT);

   // printf ("H5Acreate returns: %i\n", att);

    ret = H5Dwrite(att, strType,dataspace,dataspace, H5P_DEFAULT, str);

   // printf ("H5Awrite returns: %i\n", ret);

    ret = H5Dclose(att);

   // printf ("H5Aclose returns: %i\n", ret);

    ret = H5Gclose(root);

   // printf ("H5Gclose returns: %i\n", ret);

    ret = H5Tclose(type);

   // printf ("H5Tclose returns: %i\n", ret);

    ret = H5Sclose(dataspace);

   // printf ("H5Sclose returns: %i\n", ret);

    ret = H5Fclose(file);

   // printf ("H5Fclose returns: %i\n", ret);

}

static void read_vlstr_attr ()

{

    hid_t file, root, att;

    hid_t type;

    herr_t ret;

    char* string_att[VDIM];

   char **str;

    int i;

   hsize_t dims[]={1};

    file = H5Fopen(VFILE, H5F_ACC_RDONLY, H5P_DEFAULT);

  // printf (""H5Fopen returns: %i\n", file);

    /* Create a datatype to refer to. */

    type = H5Tcopy (H5T_C_S1);

   hid_t strType = H5Tcreate(H5T_COMPOUND,sizeof(str));

   H5Tinsert(strType,"var str",0,type);

    ret = H5Tset_size (type, H5T_VARIABLE);

  // printf (""H5Tset_size returns: %i\n", ret);

    root = H5Gopen(file, "/");

  // printf (""H5Gopen returns: %i\n", root);

   att = H5Dopen(root, "VarStrAtt");

  // printf (""H5Aopen_name returns: %i\n", att);

   str = new char*[4];

   hid_t dataspace = H5Screate_simple(VRANK, dims, NULL);

   ret = H5Dread(att, strType, dataspace, H5Dget_space(att),
H5P_DEFAULT, str);

    //for (i=0; i<VDIM; i++)

    // printf ("" (%i) %s\n", i, string_att[i]);

  // printf (""\n");

    free(string_att);

    ret = H5Dclose(att);

  // printf (""H5Aclose returns: %i\n", ret);

    ret = H5Tclose(type);

  // printf (""H5Tclose returns: %i\n", ret);

    ret = H5Gclose(root);

  // printf (""H5Gclose returns: %i\n", ret);

    ret = H5Fclose(file);

  // printf (""H5Fclose returns: %i\n", ret);

}

int _tmain(int argc, _TCHAR* argv[])

{

   write_vlstr_attr();

  read_vlstr_attr();

   return 0;

}

Hi Ramakrishnan,

All,
My aim is to write an array of strings ( created dynamically into a dataset (1D dataset ). I have a variable char ** strings defined . Before writing this array is populated as given below .
Based on length strings = new char*[length];

Fill each strings[i] .

The dataset consists of a compound datatype wherein one of the components is a variable length string array .

type = H5Tcopy (H5T_C_S1);
ret = H5Tset_size (type, H5T_VARIABLE);

//One of the components of the datatype is – comType has other components as well
H5Tinsert(comType,"var str",0,type);

H5Dwrite writes all the strings to the given file as below in hdf5 file ( output from h5dump )
         "\320\310\362\0138\312\362\013\350\312\362\013\230\314\362\013\370\314\362\013H\315\362\013\375\375\375\375\253\253\253\253\253\253\253\253\356\376\356\376"

The number of strings written were 6. I stored 6 also a a separate value in the dataset

When reading the length is read first and memory allocated as
  strings = new char*[length];

Then H5Dread is used to read in the value from hdf5 file . I get only junk values and not the one that is written .

  It looks like your compiler's 'new' allocation method and it's 'malloc' allocation method are different. I can think of two ways to try to address this sort of issue:
  - Switch your allocation for writing the strings from using 'new' to using 'malloc'
  - Use the H5Pset_vlen_mem_manager() routine to give the HDF5 library a routine to call for allocating memory for variable-length types.

    Quincey

···

On May 26, 2008, at 4:56 AM, Ramakrishnan Iyer wrote:

I also tried to modify one of the existing examples . But no success .

#ifdef __cplusplus
extern "C" {
#endif

#include "stdafx.h"
#include "..\..\hdf5\hdf5\hdf5-1.6.5_PC\src\hdf5.h"
//C:\HDF5\hdf5\hdf5\hdf5-1.6.5_PC\src
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>

#define VFILE "vlstra.h5"
#define VRANK 1
#define VDIM 4

static void write_vlstr_attr ()
{
    hid_t file, root, dataspace, att;
    hid_t type;
    herr_t ret;
    hsize_t dims[]={1};
    const char *string_att[VDIM] = {"string1",
                                    "string2",
                                    "string3",
                                    "string4", };

   char **str;

    file = H5Fcreate(VFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
   // printf ("H5Fcreate returns: %i\n", file);

    /* Create a datatype to refer to. */
    type = H5Tcopy (H5T_C_S1);
   // printf ("H5Tcopy returns: %i\n", type);

    ret = H5Tset_size (type, H5T_VARIABLE);
   // printf ("H5Tset_size returns: %i\n", ret);

   hid_t strType = H5Tcreate(H5T_COMPOUND,sizeof(str));
   H5Tinsert(strType,"var str",0,type);

    root = H5Gopen(file, "/");
   // printf ("H5Gopen returns: %i\n", root);

    dataspace = H5Screate_simple(VRANK, dims, NULL);
   // printf ("H5Screate returns: %i\n", dataspace);

   str = new char*[4];
   for(int j=0;j<4 ; j++)
   {
         str[j] = new char[8];
         strcpy(str[j],string_att[j]);
   }

    att = H5Dcreate(root, "VarStrAtt", strType, dataspace, H5P_DEFAULT);
   // printf ("H5Acreate returns: %i\n", att);

    ret = H5Dwrite(att, strType,dataspace,dataspace, H5P_DEFAULT, str);
   // printf ("H5Awrite returns: %i\n", ret);

    ret = H5Dclose(att);
   // printf ("H5Aclose returns: %i\n", ret);

    ret = H5Gclose(root);
   // printf ("H5Gclose returns: %i\n", ret);

    ret = H5Tclose(type);
   // printf ("H5Tclose returns: %i\n", ret);

    ret = H5Sclose(dataspace);
   // printf ("H5Sclose returns: %i\n", ret);

    ret = H5Fclose(file);
   // printf ("H5Fclose returns: %i\n", ret);
}

static void read_vlstr_attr ()
{
    hid_t file, root, att;
    hid_t type;
    herr_t ret;
    char* string_att[VDIM];
   char **str;
    int i;
   hsize_t dims[]={1};

    file = H5Fopen(VFILE, H5F_ACC_RDONLY, H5P_DEFAULT);
  // printf (""H5Fopen returns: %i\n", file);

    /* Create a datatype to refer to. */
    type = H5Tcopy (H5T_C_S1);
   hid_t strType = H5Tcreate(H5T_COMPOUND,sizeof(str));
   H5Tinsert(strType,"var str",0,type);

    ret = H5Tset_size (type, H5T_VARIABLE);
  // printf (""H5Tset_size returns: %i\n", ret);

    root = H5Gopen(file, "/");
  // printf (""H5Gopen returns: %i\n", root);

   att = H5Dopen(root, "VarStrAtt");
  // printf (""H5Aopen_name returns: %i\n", att);
   str = new char*[4];

   hid_t dataspace = H5Screate_simple(VRANK, dims, NULL);
   ret = H5Dread(att, strType, dataspace, H5Dget_space(att), H5P_DEFAULT, str);

    //for (i=0; i<VDIM; i++)
    // printf ("" (%i) %s\n", i, string_att[i]);
  // printf (""\n");

    free(string_att);

    ret = H5Dclose(att);
  // printf (""H5Aclose returns: %i\n", ret);

    ret = H5Tclose(type);
  // printf (""H5Tclose returns: %i\n", ret);

    ret = H5Gclose(root);
  // printf (""H5Gclose returns: %i\n", ret);

    ret = H5Fclose(file);
  // printf (""H5Fclose returns: %i\n", ret);

}

int _tmain(int argc, _TCHAR* argv[])
{
   write_vlstr_attr();
  read_vlstr_attr();
   return 0;
}

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

Hi Ram,

It looks like our original vlstra.c had an error (one has to free each of 4 strings). The modified program is attached.

I am also attaching an example program to write and read VL string datatset (it can be found under http://www.hdfgroup.uiuc.edu/UserSupport/code-examples/, Strings, Variable Length String (fixed)). And I also modified your program and made it to work (attached).

Please notice that vlstra.c and vlstrd.c free memory differently: for the attribute we just use C free call; for the datasets, HDF5 provides H5Dvlen_reclaim function to release memory allocated by the HDF5 library while reading strings back.

Your program had some other issues: you were using array of 4 strings, but the dataset was one dimensional with the dimension size equal to 1, i.e. you could write only one string. I changed dims to 4.

I also was not sure why did you need to use a compound datatype (therefore, I removed it :wink: ).
If you want to write a dataset with one element, which is an array of 4 strings, then you have to use an array datatype with the VL string as a base type for the dataset.

But may be I misinterpreted what you were trying to do. Please let me know if the attached examples clarify the VL string usage.

Thank you!

Elena

vlstra.c (2.8 KB)

vlsrtd.c (4.88 KB)

user.c (3.25 KB)

···

On May 26, 2008, at 4:56 AM, Ramakrishnan Iyer wrote:

All,
My aim is to write an array of strings ( created dynamically into a dataset (1D dataset ). I have a variable char ** strings defined . Before writing this array is populated as given below .
Based on length strings = new char*[length];

Fill each strings[i] .

The dataset consists of a compound datatype wherein one of the components is a variable length string array .

type = H5Tcopy (H5T_C_S1);
ret = H5Tset_size (type, H5T_VARIABLE);

//One of the components of the datatype is – comType has other components as well
H5Tinsert(comType,"var str",0,type);

H5Dwrite writes all the strings to the given file as below in hdf5 file ( output from h5dump )
         "\320\310\362\0138\312\362\013\350\312\362\013\230\314\362\013\370\314\362\013H\315\362\013\375\375\375\375\253\253\253\253\253\253\253\253\356\376\356\376"

The number of strings written were 6. I stored 6 also a a separate value in the dataset

When reading the length is read first and memory allocated as
  strings = new char*[length];

Then H5Dread is used to read in the value from hdf5 file . I get only junk values and not the one that is written .

I also tried to modify one of the existing examples . But no success .

#ifdef __cplusplus
extern "C" {
#endif

#include "stdafx.h"
#include "..\..\hdf5\hdf5\hdf5-1.6.5_PC\src\hdf5.h"
//C:\HDF5\hdf5\hdf5\hdf5-1.6.5_PC\src
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>

#define VFILE "vlstra.h5"
#define VRANK 1
#define VDIM 4

static void write_vlstr_attr ()
{
    hid_t file, root, dataspace, att;
    hid_t type;
    herr_t ret;
    hsize_t dims[]={1};
    const char *string_att[VDIM] = {"string1",
                                    "string2",
                                    "string3",
                                    "string4", };

   char **str;

    file = H5Fcreate(VFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
   // printf ("H5Fcreate returns: %i\n", file);

    /* Create a datatype to refer to. */
    type = H5Tcopy (H5T_C_S1);
   // printf ("H5Tcopy returns: %i\n", type);

    ret = H5Tset_size (type, H5T_VARIABLE);
   // printf ("H5Tset_size returns: %i\n", ret);

   hid_t strType = H5Tcreate(H5T_COMPOUND,sizeof(str));
   H5Tinsert(strType,"var str",0,type);

    root = H5Gopen(file, "/");
   // printf ("H5Gopen returns: %i\n", root);

    dataspace = H5Screate_simple(VRANK, dims, NULL);
   // printf ("H5Screate returns: %i\n", dataspace);

   str = new char*[4];
   for(int j=0;j<4 ; j++)
   {
         str[j] = new char[8];
         strcpy(str[j],string_att[j]);
   }

    att = H5Dcreate(root, "VarStrAtt", strType, dataspace, H5P_DEFAULT);
   // printf ("H5Acreate returns: %i\n", att);

    ret = H5Dwrite(att, strType,dataspace,dataspace, H5P_DEFAULT, str);
   // printf ("H5Awrite returns: %i\n", ret);

    ret = H5Dclose(att);
   // printf ("H5Aclose returns: %i\n", ret);

    ret = H5Gclose(root);
   // printf ("H5Gclose returns: %i\n", ret);

    ret = H5Tclose(type);
   // printf ("H5Tclose returns: %i\n", ret);

    ret = H5Sclose(dataspace);
   // printf ("H5Sclose returns: %i\n", ret);

    ret = H5Fclose(file);
   // printf ("H5Fclose returns: %i\n", ret);
}

static void read_vlstr_attr ()
{
    hid_t file, root, att;
    hid_t type;
    herr_t ret;
    char* string_att[VDIM];
   char **str;
    int i;
   hsize_t dims[]={1};

    file = H5Fopen(VFILE, H5F_ACC_RDONLY, H5P_DEFAULT);
  // printf (""H5Fopen returns: %i\n", file);

    /* Create a datatype to refer to. */
    type = H5Tcopy (H5T_C_S1);
   hid_t strType = H5Tcreate(H5T_COMPOUND,sizeof(str));
   H5Tinsert(strType,"var str",0,type);

    ret = H5Tset_size (type, H5T_VARIABLE);
  // printf (""H5Tset_size returns: %i\n", ret);

    root = H5Gopen(file, "/");
  // printf (""H5Gopen returns: %i\n", root);

   att = H5Dopen(root, "VarStrAtt");
  // printf (""H5Aopen_name returns: %i\n", att);
   str = new char*[4];

   hid_t dataspace = H5Screate_simple(VRANK, dims, NULL);
   ret = H5Dread(att, strType, dataspace, H5Dget_space(att), H5P_DEFAULT, str);

    //for (i=0; i<VDIM; i++)
    // printf ("" (%i) %s\n", i, string_att[i]);
  // printf (""\n");

    free(string_att);

    ret = H5Dclose(att);
  // printf (""H5Aclose returns: %i\n", ret);

    ret = H5Tclose(type);
  // printf (""H5Tclose returns: %i\n", ret);

    ret = H5Gclose(root);
  // printf (""H5Gclose returns: %i\n", ret);

    ret = H5Fclose(file);
  // printf (""H5Fclose returns: %i\n", ret);

}

int _tmain(int argc, _TCHAR* argv[])
{
   write_vlstr_attr();
  read_vlstr_attr();
   return 0;
}