fread crashes on pointer

Started by
2 comments, last by Potatoman 12 years, 1 month ago
Hello, I got this strange problem that perhaps someone with better knowledge of C++ than me could explain.
For some reasion the progrem crashes when trying to read data into a pointer to regionVoxel.
However, reading into a voxel allocated on the stack and then copy it over to the regionVoxel works...




// * This is how I call the read_region function
voxel regionVoxel;
...
result = read_region(region_filename.str(), block_dir.str(), &regionVoxel);

int read_region(string regionFile, string blockDir, voxel *regionVoxel)
{
voxel tmp;
if(file_exists(blockDir.c_str()))
return ABYDOS_TERRAIN_MIXED_REGION;

if(!file_exists(regionFile.c_str()))
return ABYDOS_TERRAIN_READ_ERROR;

FILE *file = openFile(regionFile.c_str());

if(file == NULL)
return ABYDOS_TERRAIN_READ_ERROR;

memset(regionVoxel, 0, sizeof(voxel));
memset(&tmp, 0, sizeof(voxel));

// * In my world, &tmp and *regionVoxel is kind of the same, why a pointer
// * to voxel can not be read, but a pointer when taken by the adress opererator can eludes me.
//fread((void *) regionVoxel->density, 1, 1, file);
//fread((void *) regionVoxel->material, 2, 1, file);
read(&tmp.density, 1, 1, file);
fread(&tmp.material, 2, 1, file);
*regionVoxel = tmp;
closeFile(file);

regionVoxel->material = ntohs(regionVoxel->material);
return ABYDOS_TERRAIN_SHARED_REGION;
}
Advertisement
You mean
fread((void *) &regionVoxel->density, 1, 1, file);
fread((void *) &regionVoxel->material, 2, 1, file);


The things you are converting to (void *) should be the addresses of the fields you want to fill out, not their values.
Thanks, I actually just noticed that I wanted the address of density and material inside the struct :)
So I changed to this and it worked.


fread((void*) &(regionVoxel->density), 1, 1, file);
fread((void*) &(regionVoxel)->density, 1, 1, file);

Thanks, I actually just noticed that I wanted the address of density and material inside the struct smile.png
So I changed to this and it worked.


fread((void*) &(regionVoxel->density), 1, 1, file);
fread((void*) &(regionVoxel)->density, 1, 1, file);



To avoid similar issues in future consider using static_cast, this provides the compiler with context to confirm the cast is valid, so you don't have things like this creep in by accident


unsigned int val = 0xcdcdcdcd;
void* ptr1 = static_cast<void*>(val); // error C2440: 'static_cast' : cannot convert from 'unsigned int' to 'void *'
void* ptr2 = static_cast<void*>(&val); // ok
void* ptr3 = reinterpret_cast<void*>(val); // if you insist..

This topic is closed to new replies.

Advertisement