diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2003-10-10 15:23:48 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2003-10-10 15:23:48 (GMT) |
commit | 90fb9e2a77fc4ff7cf894fea7bc06b5c4ffc851c (patch) | |
tree | fd15f1d7fe6079bb033c96eab56732f679fdfad6 /src | |
parent | c71ef4801c27e24a605010d81772adadb6cc921e (diff) | |
download | hdf5-90fb9e2a77fc4ff7cf894fea7bc06b5c4ffc851c.zip hdf5-90fb9e2a77fc4ff7cf894fea7bc06b5c4ffc851c.tar.gz hdf5-90fb9e2a77fc4ff7cf894fea7bc06b5c4ffc851c.tar.bz2 |
[svn-r7595] Purpose:
Bug fix
Description:
The 'char *' type is one of the "strongly" aligned types on Crays, but
a 'void *' is "weakly" aligned. So, assigning a 'void *' (pointing to a
location to place a 'char *') to a 'char **' can change the pointer value
during the assignment.
Solution:
Don't alias the 'void *' where the variable-length information ('char *'
or 'hvl_t') will go. Use a temporary variable on the stack to build up the
information about the VL string or sequence and then memcpy() the temporary
variable directly to the location pointed to with the 'void *'
Platforms tested:
FreeBSD 4.9 (sleipnir)
Cray SV1 (wind)
specific to Cray problems, h5committest not necessary.
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Tvlen.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index e74bca7..1946136 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -353,7 +353,7 @@ H5T_vlen_seq_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *vl_addr, void *buf, { H5MM_allocate_t alloc_func; /* Vlen allocation function */ void *alloc_info; /* Vlen allocation information */ - hvl_t *vl=(hvl_t *)vl_addr; /* Pointer to the user's hvl_t information */ + hvl_t vl; /* Temporary hvl_t to use during operation */ size_t len; H5P_genplist_t *plist; /* Property list */ herr_t ret_value=SUCCEED; /* Return value */ @@ -361,7 +361,7 @@ H5T_vlen_seq_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *vl_addr, void *buf, FUNC_ENTER_NOAPI(H5T_vlen_seq_mem_write, FAIL) /* check parameters */ - assert(vl); + assert(vl_addr); assert(buf); if(seq_len!=0) { @@ -378,23 +378,26 @@ H5T_vlen_seq_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *vl_addr, void *buf, HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value") if(alloc_func!=NULL) { - if(NULL==(vl->p=(alloc_func)(len,alloc_info))) + if(NULL==(vl.p=(alloc_func)(len,alloc_info))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") } /* end if */ else { /* Default to system malloc */ - if(NULL==(vl->p=H5MM_malloc(len))) + if(NULL==(vl.p=H5MM_malloc(len))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") } /* end else */ /* Copy the data into the newly allocated buffer */ - HDmemcpy(vl->p,buf,len); + HDmemcpy(vl.p,buf,len); } /* end if */ else - vl->p=NULL; + vl.p=NULL; /* Set the sequence length */ - H5_ASSIGN_OVERFLOW(vl->len,seq_len,hsize_t,size_t); + H5_ASSIGN_OVERFLOW(vl.len,seq_len,hsize_t,size_t); + + /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ + HDmemcpy(vl_addr,&vl,sizeof(hvl_t)); done: FUNC_LEAVE_NOAPI(ret_value) @@ -490,7 +493,6 @@ H5T_vlen_str_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *vl_addr, void *buf, { H5MM_allocate_t alloc_func; /* Vlen allocation function */ void *alloc_info; /* Vlen allocation information */ - char **s=(char **)vl_addr; /* Pointer to the user's hvl_t information */ char *t; /* Pointer to temporary buffer allocated */ size_t len; /* Maximum length of the string to copy */ H5P_genplist_t *plist; /* Property list */ @@ -526,7 +528,7 @@ H5T_vlen_str_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *vl_addr, void *buf, t[len]='\0'; /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - HDmemcpy(s,&t,sizeof(char *)); + HDmemcpy(vl_addr,&t,sizeof(char *)); done: FUNC_LEAVE_NOAPI(ret_value) /*lint !e429 The pointer in 't' has been copied */ |