我有一个函数将一堆float32值重新转换为int32,它一直运行到它尝试读取的最后一个float32。即使浮点数不是数组中的最后一个值(即我将FOR循环设置为提前停止),它仍会返回无效的读取,就好像它试图在数组外部读取一样。
int i, nvoxels;
nvoxels = roi->dim[1] * roi->dim[2] * roi->dim[3];
for (i = 0; i<nvoxels; i++) {
roiData[i] = (int)round(((double *)(roi->data))[i]); //line 400
}
roidata在重铸函数之外定义为:
int* roiData = MallocAndCheck(sizeof(int) * roi->dim[1] * roi->dim[2] * roi->dim[3], 1);
roiData是一个新数组,用于保存从roi->数据中获取的int值(这是一个带有一堆指针值的void *)。在上面,我们从roi-&gt;数据中获取double *,舍入它们的值,并将其作为int存储在roiData中存储。我已多次确认错误与明确读取外部错误无关。数据(它应该有1,048,576个值,它将处理1,048,576个值),但即使我告诉它停止在20,000个值,错误仍然会发生。除了返回0/1语句之外,在for之后没有其他代码。
(MallocAndCheck是一个自定义内存函数,它包含malloc,空指针检查和指针注册,以便我可以在退出时轻松清理。我们可以假设它正常工作)它的原型是MallocAndCheck(int size,int shouldRegister) (应该注册的是它是否应该在退出时跟踪指针以进行清理,否则我将手动处理清理)。
==13348== Invalid read of size 8
==13348== at 0x402293: nii_recast_to_int32 (pow_filter.c:400)
==13348== by 0x402293: RecastRoi (pow_filter.c:313)
==13348== by 0x401450: main (pow_filter.c:50)
==13348== Address 0x5a03040 is 0 bytes after a block of size 4,194,304 alloc'd
==13348== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13348== by 0x4109F9: nifti_image_load (nifti1_io.c:4547)
==13348== by 0x417CF7: nifti_image_read (nifti1_io.c:3904)
==13348== by 0x401EBF: OpenNiftiImageFile (pow_filter.c:271)
==13348== by 0x4013EA: main (pow_filter.c:46)
这只会在最后一次读取数据时触发,无论你停止在数组中的哪个位置。 (roi是“nifti”函数返回的指针)。
编辑:额外信息:
roi定义为:
typedef struct { /*!< Image storage struct **/
int ndim ; /*!< last dimension greater than 1 (1..7) */
int nx ; /*!< dimensions of grid array 0 */
int ny ; /*!< dimensions of grid array 1 */
int nz ; /*!< dimensions of grid array 2 */
int nt ; /*!< dimensions of grid array 3 */
int nu ; /*!< dimensions of grid array 4 */
int nv ; /*!< dimensions of grid array 5 */
int nw ; /*!< dimensions of grid array 6 */
int dim[8] ; /*!< dim[0]=ndim, dim[1]=nx, etc. */
size_t nvox ; /*!< number of voxels = nx*ny*nz*...*nw */
int nbyper ; /*!< bytes per voxel, matches datatype */
int datatype ; /*!< type of data in voxels: DT_* code */
float dx ; /*!< grid spacings */
float dy ; /*!< grid spacings */
float dz ; /*!< grid spacings */
float dt ; /*!< grid spacings */
float du ; /*!< grid spacings */
float dv ; /*!< grid spacings */
float dw ; /*!< grid spacings */
float pixdim[8] ; /*!< pixdim[1]=dx, etc. */
float scl_slope ; /*!< scaling parameter - slope */
float scl_inter ; /*!< scaling parameter - intercept */
float cal_min ; /*!< calibration parameter, minimum */
float cal_max ; /*!< calibration parameter, maximum */
int qform_code ; /*!< codes for (x,y,z) space meaning */
int sform_code ; /*!< codes for (x,y,z) space meaning */
int freq_dim ; /*!< indexes (1,2,3, or 0) for MRI */
int phase_dim ; /*!< directions in dim[]/pixdim[] */
int slice_dim ; /*!< directions in dim[]/pixdim[] */
int slice_code ; /*!< code for slice timing pattern */
int slice_start ; /*!< index for start of slices */
int slice_end ; /*!< index for end of slices */
float slice_duration ; /*!< time between individual slices */
/*! quaternion transform parameters
[when writing a dataset, these are used for qform, NOT qto_xyz] */
float quatern_b , quatern_c , quatern_d ,
qoffset_x , qoffset_y , qoffset_z ,
qfac ;
mat44 qto_xyz ; /*!< qform: transform (i,j,k) to (x,y,z) */
mat44 qto_ijk ; /*!< qform: transform (x,y,z) to (i,j,k) */
mat44 sto_xyz ; /*!< sform: transform (i,j,k) to (x,y,z) */
mat44 sto_ijk ; /*!< sform: transform (x,y,z) to (i,j,k) */
float toffset ; /*!< time coordinate offset */
int xyz_units ; /*!< dx,dy,dz units: NIFTI_UNITS_* code */
int time_units ; /*!< dt units: NIFTI_UNITS_* code */
int nifti_type ; /*!< 0==ANALYZE, 1==NIFTI-1 (1 file),
2==NIFTI-1 (2 files),
3==NIFTI-ASCII (1 file) */
int intent_code ; /*!< statistic type (or something) */
float intent_p1 ; /*!< intent parameters */
float intent_p2 ; /*!< intent parameters */
float intent_p3 ; /*!< intent parameters */
char intent_name[16] ; /*!< optional description of intent data */
char descrip[80] ; /*!< optional text to describe dataset */
char aux_file[24] ; /*!< auxiliary filename */
char *fname ; /*!< header filename (.hdr or .nii) */
char *iname ; /*!< image filename (.img or .nii) */
int iname_offset ; /*!< offset into iname where data starts */
int swapsize ; /*!< swap unit in image data (might be 0) */
int byteorder ; /*!< byte order on disk (MSB_ or LSB_FIRST) */
void *data ; /*!< pointer to data: nbyper*nvox bytes */
int num_ext ; /*!< number of extensions in ext_list */
nifti1_extension * ext_list ; /*!< array of extension structs (with data) */
analyze_75_orient_code analyze75_orient; /*!< for old analyze files, orient */
} nifti_image ;
如您所见,nifti_image-&gt; data是一个void *,其存储数据类型为nifti_image-&gt; datatype。
在我的代码中,我检查了上面代码所针对的数据类型,它执行上面的操作。
在这种特殊情况下,我知道数据类型应该是float32。