NO

Author Topic: Cast to pointer to big structure  (Read 5289 times)

Alessio

  • Guest
Cast to pointer to big structure
« on: October 14, 2008, 05:01:24 PM »
Hello,

I've huge binary file that contains a dataset of 300 columns x 180 rows x 365 days x N years
I mapped this file in memory and cast his pointer from void * to following structure:

Code: [Select]

#define __ROW__ 180
#define __COLUMN__ 300
#define __DAY__ 365

typedef struct
{
INT iValue[__DAY__][__ROW__][__COLUMN__];

} YEAR, *LPYEAR;


the compiler warns me that there are "More than 65535 bytes in 'int [365][180][300]".
It is valid to cast to this type of structure, or I preferred to cast to pointer to int ?
If it is preferred to cast to pointer to int, how can I easily access to data ? Using defines and various multiplier ?

thanks.



JohnF

  • Guest
Re: Cast to pointer to big structure
« Reply #1 on: October 15, 2008, 11:53:18 AM »
I'm not certain what you are asking here.

As a general rule you should post some code concerning the problem, this gives the reader more chance of understanding the question.

Accessing the struct should not be a problem as far as I can tell.

John

Alessio

  • Guest
Re: Cast to pointer to big structure
« Reply #2 on: October 15, 2008, 12:53:42 PM »
OK,

this is the code:

Code: [Select]

// PROGRAM TO PARSE A BINARY FILE WITH DATASET OF 300 columns x 180 rows x 365 days x N years INTEGER VALUES

//
#define STRICT
#define WIN32_LEAN_AND_MEAN

//
#include <windows.h>
#include <stdio.h>

#define __ROW__ 180
#define __COLUMN__ 300
#define __DAY__ 365

//
typedef struct
{
INT iValue[__DAY__][__ROW__][__COLUMN__];

} YEAR, *LPYEAR;

//
int main(void)
{
// MAP FILE IN MEMORY

HANDLE hFile = CreateFile("test.bin", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if ( INVALID_HANDLE_VALUE == hFile )
{
return -1;
}

DWORD dwFileSize = GetFileSize(hFile, NULL);
if ( INVALID_FILE_SIZE == dwFileSize )
{
CloseHandle(hFile);

return -1;
}

HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if ( NULL == hMapping )
{
CloseHandle(hFile);

return -1;
}

LPYEAR lpYear = (LPYEAR)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

CloseHandle(hMapping);
CloseHandle(hFile);

if ( NULL == lpYear )
{
return -1;
}

// FILESIZE
size_t iSize = 0;
MEMORY_BASIC_INFORMATION mbi = { 0 };

if ( VirtualQuery(lpYear, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) >= sizeof(MEMORY_BASIC_INFORMATION) )
{
iSize = min(dwFileSize, mbi.RegionSize);
}
else
{
iSize = dwFileSize;
}

// NUMBER OF YEARS IN FILE
INT iYears = iSize/sizeof(YEAR);

if ( iYears > 0 )
{

//
printf("filesize is %d\n", iSize);
printf("year founded on file: %d\n", iYears);

// SHOW VALUE OF
// FIRST YEAR
// FIRST DAY
// FIRST ROW
// FIRST COLUMN
printf("%d\n", lpYear[0].iValue[0][0][0]);

// SHOW VALUE OF
// FIRST YEAR
// LAST DAY
// LAST ROW
// 80th COLUMN
printf("%d\n", lpYear[0].iValue[__DAY__-1][__ROW__-1][80]);
}

//
UnmapViewOfFile(lpYear);

//
return 0;
}


Can this considered a valid approach or there is a another solution ?

JohnF

  • Guest
Re: Cast to pointer to big structure
« Reply #3 on: October 15, 2008, 01:37:04 PM »
It looks ok to me.

There is no need to concern yourself with the cast issue, casting from void* to any other type is ok without any explicit casting.

there is no need to cast this for example -

LPYEAR lpYear = (LPYEAR)MapViewOfFile(...);

the return from the function MapViewOfFile being void* is automatically cast to LPYEAR.

Could be
LPYEAR lpYear = MapViewOfFile(...);

EDIT:

The only issue that could arise is if your struct had padding bytes, then if the data in the file was contiguous you would get bad results when indexing the various struct offsets.

Your present struct does not have padding bytes if the default setting is used.

John
« Last Edit: October 15, 2008, 01:46:25 PM by JohnF »

Alessio

  • Guest
Re: Cast to pointer to big structure
« Reply #4 on: October 15, 2008, 02:45:01 PM »
thank you, but I've not undestand the padding bytes thing.
How can my struct have padding byte ?
The data in the file is contiguous, I've to use pragma pack ?

JohnF

  • Guest
Re: Cast to pointer to big structure
« Reply #5 on: October 15, 2008, 03:29:03 PM »
thank you, but I've not undestand the padding bytes thing.
How can my struct have padding byte ?
The data in the file is contiguous, I've to use pragma pack ?

Your struct does not have padding bytes now and if you don't change it you will be ok. No need to use pragma pack.

But if your struct were different, say for another job you were doing, be careful. Perhaps I should not have mentioned it.

John



pgoh

  • Guest
Re: Cast to pointer to big structure
« Reply #6 on: November 11, 2008, 08:32:59 AM »
Code: [Select]

#define __ROW__ 180
#define __COLUMN__ 300
#define __DAY__ 365

typedef struct
{
INT iValue[__DAY__][__ROW__][__COLUMN__];

} YEAR, *LPYEAR;


the compiler warns me that there are "More than 65535 bytes in 'int [365][180][300]".

The compiler is complaining because you've declared a struct that could make 365 * 180 * 300 integers on the stack, which results in 365 * 190 * 300 * 4 bytes being allocated on stack. This is equal to about 80 MB of allocations on the stack, which can only support 2 MB of allocations (IIRC).

The reason you code works is because you've luckily used a pointer to the structure by declaring an LPYEAR. If you had declared a YEAR instead, your program would crash with a stack overflow.