wrecker's Avatar, Join Date: Mar 2007
Go4Expert Member
But this doesnot work with calculating the size of float and other data types.
aperisic's Avatar, Join Date: Feb 2008
Newbie Member
All solutions compare the size to char

The third is simplest and is applicable to any class or structure besides basic types. Other two are more complex but interesting on their own nevertheless.

Code:
// if you prefere size in bytes
#define BYTE_SIZE 8 

// if you prefere size in bits
// #define BYTE_SIZE 1 

int sizeChar()
{
	static int c = sizeChar();
	if (c != 0) return c; // call it only first time

	c = 1;
	char t = (char)1;
	while ( t <<= 1 ) c++;
	c /= BYTE_SIZE;

	return c;

}

template<typename T>
int my_sizeof_3()
{
	int c = sizeChar();

	T t[2];
	char* a[2];
	
	a[0] = (char*)&t[0]; // convert to char
	a[1] = (char*)&t[1]; // convert to char at the second element
	
	int n = 0;

	while (a[1] != a[0]) // go back until first and second match
	{
		a[1]--; 
		n++;
	}

	return n*c;
}
The first solution uses two elements one after another and then changes slowly the entire portion of memory to see when the first element does not change any more. It means we have started to change the bytes in the second element and there we can calculate the size.
The second solution needs assumed maximum expected size and then it shrinks and changes memory byte by byte and examine at which moment our element would show any change. At that moment we are inside the memory that is occupied by our element and we can calculate the size.

sizeChar is there only if we really want to have the size of char calculated first

Both functions can give size in bytes or size in bits depending on BYTE_SIZE definition.


For the size of larger structure like class and struct we need the solution number 3

Code:
// if you prefere size in bytes
#define BYTE_SIZE 8 

// if you prefere size in bits
// #define BYTE_SIZE 1 

int sizeChar()
{
	static int c = sizeChar();
	if (c != 0) return c; // call it only first time

	c = 1;
	char t = (char)1;
	while ( t <<= 1 ) c++;
	c /= BYTE_SIZE;

	return c;

}

template<typename T>
int my_sizeof_1()
{
	int c = sizeChar();

	T e[2];

	e[0] = 0;
	e[1] = 0;

	char* str = (char*)e;

	int n = 0;
	T p;

	do
	{
		p = e[0];
		str[n++] = 1;
	}
	while(e[0] != p);

	return (n-1)*c;
}

#define MAX_EXPECTED_SIZE 20

template<typename T>
int my_sizeof_2(int max_size = MAX_EXPECTED_SIZE)
{
	int c = sizeChar();

	char* e;

	while(1)
	{
		e = new char[max_size];
		
		for(int i = 0; i < max_size-1; i++ )
			e[i] = 0;

		e[max_size-1] = 1; // set only last element to 1

		T* y = (T*)e; 	// convert to see if type value
// would remain 0

		if(*y != 0) 
		{
			delete e;
			break;
		}

		delete [] e;
		
		max_size--;
	}

	return max_size*c;
}
Usage

Code:
struct Sample
{
	int a,b,c,d,e,f,g;
};

	int size = my_sizeof_1<int>();
	size = my_sizeof_1<double>();
	size = my_sizeof_1<char>();
	size = my_sizeof_1<long int>();

	size = my_sizeof_2<int>();
	size = my_sizeof_2<double>();
	size = my_sizeof_2<char>();
	size = my_sizeof_2<long int>();

	size = my_sizeof_3<int>();
	size = my_sizeof_3<double>();
	size = my_sizeof_3<char>();
	size = my_sizeof_3<long int>();
	size = my_sizeof_3<Sample>();
aperisic's Avatar, Join Date: Feb 2008
Newbie Member
Of course, this is the fastest (sizeChar and BYTE_DEFINE as above)

Code:
template<typename  T>
int my_sizeof_4()
{
	int  c = sizeChar();

	T* t = NULL;

	return  ((char*)(t+1)-(char*)t)*c;
}
Observe that this would not be perfectly safe if we would have t++ anywhere since this would create a pointer to undefined memory location, but t + 1 is more OK. The only problem is that t+1 implicitly uses something similar to sizeof so it might look like cheating
Only my_sizeof_3 has its own logic applied because it creates objects first. But even there somebody should know the size of the object, so it is cheating anyhow.
What I want to say, even if you don't use sizeof to find the size, the system this way or another must.
imrantechi's Avatar, Join Date: Feb 2008
Ambitious contributor
nice one
mohan kumar's Avatar, Join Date: May 2011
Newbie Member
#include<stdio.h>
void main()
{
float i;

float * p = &i;

float * q= p;

p++;

printf("%d",int(p)-int(q));

}