float32 값을 int32로 다시 작성하는 함수가 있으며 마지막으로 float32가 읽을 때까지 작동합니다. float가 배열의 마지막 값이 아니더라도 (예 : FOR 루프를 일찍 중지하도록 설정 한 경우에도) 배열 외부에서 읽으려는 것처럼 잘못된 읽기가 반환됩니다.배열을 재 배열하면 마지막 값은 항상 잘못된 읽기 예외를 발생시킵니다.
int* roiData = MallocAndCheck(sizeof(int) * roi->dim[1] * roi->dim[2] * roi->dim[3], 1);
roiData가 무효 roi-> 데이터로부터 촬영 된 INT 값 (보유하는 것을 의미한다 새로운 배열 *
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은 같이 참 -_- 기능 밖에 정의 그것에 포인터 값의 무리와 함께). 위에서 우리는 roi -> 데이터에서 double *을 취하여 값을 반올림 한 다음이를 roiData에 저장하기위한 int로 캐스팅합니다. 오류가 외부 roi-> data (1,048,576 값을 가지고 있어야하며 1,048,576 값을 처리해야 함)를 명시 적으로 읽는 것과 관련이 없다는 것을 여러 번 확인했습니다. 그러나 멈추라 고 말하면 오류가 계속 발생합니다. 20,000 개의 값. 에 대한 반환 코드 0/1 이외에는 다른 코드가 없습니다.
(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)는 다음과 같이 정의됩니다 : 당신이 nifti_image- 볼 수
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-입니다> 데이터 타입 무효 *입니다.
내 코드에서 위의 코드도 위의 작업을 수행하는 데이터 형식을 확인합니다.
이 특정 경우 데이터 유형은 float32 여야합니다.
어디서나 정의 된 float32가 표시되지 않습니다. 32 비트 타입이 거의없는 double이 있습니다. valgrind는 4 백만 바이트 만 할당된다고 말하면서 1 백만 배가 일반적으로 800 만 바이트를 차지합니다. 백만 가지 값을 읽을 때 한계를 벗어납니다. 나는 모든 수의 읽기보다 적은 후에 위반이 일어났다는 어떤 증거도 보이지 않는다. 코드 및 관련 valgrind 로그와 같은 몇 가지 증거를 제시하십시오. valgrind가 줄 번호를 표시 할 수 있도록 디버그 정보로 컴파일하십시오. –
@ n.m. 당신은 실제로 내가 고려하지 않은 매우 좋은 점을 제기합니다. 나는 단순히이 정확한 문제를 이미 처리 한 프로그램을 보았 기 때문에 double *을 사용했으며 double *을 사용했습니다.float *로 전환하면 오류가 중지되지만 데이터 무결성이 유지되는지 계속 확인합니다. 제가 참조하고있는 원본 라이브러리가 32 비트 용으로 작성되었으며 64 비트 용으로 빌드하고 있다는 사실에 오류가 있는지 궁금합니다. 어둠 속에서 쐈지 만, 32-64에서 마이그레이션 할 때 고려해야 할 사항에 대한 적절한 참고 자료를 알고 계신가요? – user2835725
32-64는 정수 및 포인터 만 부동 소수점 형식의 크기에 영향을주지 않습니다. 어떤 언급도 모르겠다. 미안. –