// HACK - Create a dummy structure to pass to the XyzConnect
// function to avoid AV within the function.
int dummy = 0;
if ( NO_ERROR != ( XyzConnect( 0, L"", L"", (void**)&dummy ) )
{
TRACE( L"XyzConnect failed." );
return FALSE;
}
The values given below shall be replaced by constant expressions suitable for use in #if
preprocessing directives. Moreover, except for CHAR_BIT and MB_LEN_MAX, the
following shall be replaced by expressions that have the same type as would an
expression that is an object of the corresponding type converted according to the integer
promotions. Their implementation-defined values shall be equal or greater in magnitude
(absolute value) to those shown, with the same sign.
minimum value for an object of type int
INT_MIN -32767 // −(215 − 1)
— maximum value for an object of type int
INT_MAX +32767 // 215 − 1
struct Data
{
int iterations;
int timeofday;
};
HANDLE hThread;
unsigned threadID;
unsigned __stdcall ThreadedFunc( void* p )
{
printf("Iterations: %d\nTime of Day: %d\n", (Data*)p->iterations, (Data*)p->timeofday );
return 0;
}
void start_thread( )
{
Data d;
d.iterations = 100;
d.timeofday = 100;
hThread = (HANDLE)_beginthreadex( NULL, 0, &ThreadedFunc, &d, 0, &threadID );
}
int main()
{
start_thread( );
WaitForSingleObject( hThread, INFINITE );
CloseHandle( hThread );
}
class Object
{
int value;
... functions ...
};
class Ship : public Object
{
std::string hello_world;
... functions ...
};
int main( int argc, char** argv )
{
Object* sh = new Ship( );
delete sh;
return 0;
}
class Object
{
int value;
public:
~Object( )
{
Cleanup( );
}
void Clean( )
{
Cleanup( );
}
virtual void Cleanup( )
{
}
};
class Ship : public Object
{
void* awesome_data;
public:
virtual void Cleanup( )
{
printf("%p\n", awesome_data );
}
};
int main( int argc, char** argv )
{
Object* sh = new Ship( );
sh->Clean( );
delete sh;
return 0;
}
Just to clarify, for the first one, is the issue that you're only deleting the pointer to the ship class, and not the allocated memory itself?
std::vector, std::list, std::map
std::vector, std::list, std::map
int arr[500]; std::vector, std::list
Pop quiz:
1) What is the insertion complexity of (and why!):Code: [Select]std::vector, std::list, std::map
2) Which of the following has better caching characteristics (and why!):Code: [Select]std::vector, std::list, std::map
3) On which of the following is random access not a O(1) operation (and why!)?Code: [Select]int arr[500]; std::vector, std::list
4) Given the above information, why do iterators become invalid after a non-const operation on a data structure?
5) An std::vector with 500 elements in it does not use the same amount of memory (most of the time...) as sizeof(element)*500. Why!
You know, thinking on the subject of Hierarchy in classes, it wonder if it reveals anything about the political position of most language designers? Or possibly the working conditions?
Look at it this way, a higher Class is completely ignorant to a connected lower Class, but that Class can do everything the higher class can do, and some more...
I know that's not related, but I'm really not certain it deserves a new thread...
The elements of a vector are stored contiguously, meaning that if v is a vector<T, Allocator> where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().
In addition, it supports (amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time.
You know, thinking on the subject of Hierarchy in classes, it wonder if it reveals anything about the political position of most language designers? Or possibly the working conditions?
Look at it this way, a higher Class is completely ignorant to a connected lower Class, but that Class can do everything the higher class can do, and some more...
I know that's not related, but I'm really not certain it deserves a new thread...
I think you are thinking into this too much. The real problem is that scanning the function tables of all derived classes is an expensive operation so C++ does not do this by default but allows the programmer to use the 'virtual' keyword to selectively turn on this behavior.
I wasn't sure if you were being serious or not, but because that was not the first time I had seen that particular comment (not from you, just in general) I just figured that I would clarify it for everyone.You know, thinking on the subject of Hierarchy in classes, it wonder if it reveals anything about the political position of most language designers? Or possibly the working conditions?
Look at it this way, a higher Class is completely ignorant to a connected lower Class, but that Class can do everything the higher class can do, and some more...
I know that's not related, but I'm really not certain it deserves a new thread...
I think you are thinking into this too much. The real problem is that scanning the function tables of all derived classes is an expensive operation so C++ does not do this by default but allows the programmer to use the 'virtual' keyword to selectively turn on this behavior.
To be honest, that was intended more as a humorous observation than a genuine attempt to look into the mentality behind language design ;) But, admittedly, I probably should have made that clear :)
IssMneur: ISO/IEC 14882:2003(E) specifies (page 489)Like I said at the top of my reply, it depends on the STL that you are using.QuoteThe elements of a vector are stored contiguously, meaning that if v is a vector<T, Allocator> where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().
So I should have said any conforming implementation :P
You might be surprised to learn that a vector supports amortised constant time inserts and erases at the end:QuoteIn addition, it supports (amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time.
(we'll come back to this for question 5)
I'm pretty sure IssMneur nailed it for question 1, except that a vector is 'normally' constant time (according to the standard).
2) By this I meant for regularly accessed data in a tight loop. Vector has significantly better data locality, so will perform significantly better than other data structures where a caching system is provided that is significantly faster than accesses into main memory.The CPU's cache! I was definitely not expecting you to be talking about that level, but as I said in my response, I was not clear as to what you were getting at, as caching can mean a lot of things and levels.
5) This one you're both partially correct, but it's only a small overhead required for housekeeping.Okay, I took it at face value, that is, why is the memory usage of 500 elements in an array and 500 elements in std::vector not exactly equal.
Going back to question 1, the insert time for a vector is amortised constant.
This is achieved by OVERALLOCATING each time a reallocation and move is done.
So if you're pushing a 100 1KB objects onto a vector, you might be surprised to learn that the final vector size might be something like 150 elements (again, depends on the implementation).
Write yourself a little program comparing the return values from vector::capacity and vector::size and you'll see what I mean here.
typedef struct color {
uint screen_sig;
ubyte red;
ubyte green;
ubyte blue;
ubyte alpha;
ubyte ac_type; // The type of alphacolor. See AC_TYPE_??? defines
int is_alphacolor;
ubyte raw8;
int alphacolor;
int magic;
} color;
sizeof( color ) == x
struct foo {
char one;
int two;
char three;
};
struct bar {
char one;
char two;
int three;
};
foo size is 12 bytes while bar takes 8 bytes of memory. If we really need data to be packed one directly after another then we can use implementation defined directives (that's useful while dealing with low-level stuff).char real_filename[MAX_FILENAME_LEN];
...
memset( &real_filename, 0, sizeof(real_filename) );
char real_filename[MAX_FILENAME_LEN];
...
memset( real_filename, 0, sizeof(char)*MAX_FILENAME_LEN );
That's the way it should work, shouldn't it?memset( &real_filename, 0, sizeof(real_filename) );
Should be similar toreal_filename = 0;
I was cheating a bit, because I had to check few things in the debugger (and I'm still not sure about the whole thing, though).Code: [Select]char real_filename[MAX_FILENAME_LEN];
...
memset( &real_filename, 0, sizeof(real_filename) );
What's wrong with it, and would it work anyway?
for ( i = 0; i < pm->n_models; i++ )
{
/* HACK: This is an almighty hack because it is late at night and I don't want to screw up a vm_free */
new ( &( pm->submodel[ i ].buffer ) ) SCP_vector<buffer_data>( );
pm->submodel[ i ].Reset( );
}
struct SomeStruct
{
int x;
SomeStruct( )
: x(10)
{
}
};
SomeStruct* ss = vm_malloc( sizeof(SomeStruct) );
bool can_construe_as_integer(const char *text)
{
// trivial case; evaluates to 0
if (*text == '\0')
return true;
// number sign or digit for first char
if ((*text != '+') && (*text != '-') && !isdigit(*text))
return false;
// check digits for rest
// (why on earth do we need a const cast here? text isn't the pointer being modified!)
for (char *p = const_cast<char*>(text) + 1; *p != '\0'; p++)
{
if (!isdigit(*p))
return false;
}
return true;
}
OK, programming question time (from parselo.cpp):
What is the reason that you need const_cast?
*snip*
class Interface1
{
public:
virtual void Int11( ) = 0;
virtual void Int12( ) = 0;
};
class Interface2
{
public:
virtual void Int21( ) = 0;
virtual void Int22( ) = 0;
};
class MI : public Interface1, public Interface2
{
public:
virtual void Int11( ) { return; }
virtual void Int12( ) { return; }
virtual void Int21( ) { return; }
virtual void Int22( ) { return; }
};
int main( int argc, char** argv )
{
MI* i = new MI( );
Interface1* b = dynamic_cast< Interface1* >( i );
delete b;
MI* j = new MI( );
Interface2* c = dynamic_cast< Interface2* >( j );
delete c;
return 0;
}
cg->moveflag_dest = HUD_VAR(custom_gauge_moveflags[0]) + (Num_custom_gauges * sizeof(bool));
Today features a subtle bug from Wanderer:Code: [Select]cg->moveflag_dest = HUD_VAR(custom_gauge_moveflags[0]) + (Num_custom_gauges * sizeof(bool));
Your task:
How many bugs can you spot?
NB: HUD_VAR is a macro resolving to offsetof