Solved

Changing a struct used in legacy code: problematic?

Posted on 2007-03-22
26
300 Views
Last Modified: 2010-04-01
Ah hello.

I have some legacy code that has been compiled and built into an executable.  I also have a DLL, that expects the app to pass a structure to it.  In the legacy code, this structure was defined something like this

typedef struct _MyStruct
{
      UINT u;
      int nSize;      // = sizeof ( MyStruct )
      WCHAR* pName;
} MyStruct;

However, I now need to pass a new parameter from all new applications to the DLL.  The structure needs to be changed to something like this:

typedef struct _MyStruct
{
      UINT u;
      int nSize;      // = sizeof ( MyStruct )
      WCHAR* pName;
      DWORD dwNewParam;      // New
      WCHAR* pNewParam;      // New
} MyStruct;

So, I change the declaration of the struct in my DLL's code to be the above.  

Now, (obviously) all new applications will pass a structure like the above to the DLL; no problem there.  What I am concerned about however is how the older DLL will react to a structure that does not contain the expected number of variables.  Is the above correct, or do I need to add the new variables in at some specific place?

I am thinking that if I were to say

typedef struct _MyStruct
{
      UINT u;
      WCHAR* pNewParam;      // New
      int nSize;      // = sizeof ( MyStruct )
      WCHAR* pName;
      DWORD dwNewParam;      // New
} MyStruct;

then things might get confused if the location of variables is determined by their size: eg if the compiler/whatever expects 'nSize' to be located at some location + sizeof ( UINT ) (in the original struct, 'nSize' was declared after 'u'), it would instead find 'pNewParam' there.

Am I talking sense or am I worrying about nothing?

TIA
0
Comment
Question by:mrwad99
  • 11
  • 8
  • 7
26 Comments
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18770251
>>>> is how the older DLL will react to a structure
If you pass the new struct to the dll it most likely will work as long as you are not passing arrays of the struct type.

I strongly recommend to update the older dll as well or make a new struct like

 typedef struct _MyNewStruct
{
      struct MyStruct ms;
      DWORD dwNewParam;      // New
      WCHAR* pNewParam;      // New
} MyNewStruct;

Then pass only the first member to the dll.

Regards, Alex
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18770293
passing structs between separately compiled binaries, is always a good reason to be extra careful.
There's no 100% guarantee that the data will be packed in the struct in exactly the same way.

If possible, I would consider adding overloaded versions of the functions in the DLL for the new struct.

What are the signatures of the DLL functions ? And how do you call them ?
0
 
LVL 19

Author Comment

by:mrwad99
ID: 18770302
Thanks Alex.  

In a fashion that I am sure you are acquainted to when commenting on my questions, I would like to take apart your comments to fully understand what you mean.

>> ... it most likely will work as long as you are not passing arrays of the struct type.

Could you give an example of why that is, and what would happen if I were to pass an array of structures please?

>> I strongly recommend to update the older dll

The thing is, we have applications that are already built, but we may wish to distribute them with the new DLL, without rebuilding the application.  So the old application will always pass an old structure to the DLL, which is expecting a new structure.

>> ...or make a new struct like...

That would imply rebuilding the application code, which is not an option.  Or would it?!

Am I right about the organisation of structs, and the location of member variables being dependent on the sizes of what is already there (my last comment above)?

Thanks.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 18770327
Infinity08: thanks for participating.

>> passing structs between separately compiled binaries, is always a good reason to be extra careful.

I have never even considered that before.  Can you elaborate on "packed in the struct in exactly the same way" please?

>> ...overloaded versions of the functions in the DLL for the new struct

A very good suggestion.  Thank you.

>> What are the signatures of the DLL functions ?

MY_DLL int GetInfo ( MyStruct* pMyStruct );

where MY_DLL is __declspec (dllexport) or dllimport, as you would expect

This function is called by first loading the DLL with LoadLibrary, then GetProcAddress finds the address of the function "GetInfo", then I pass it the address of a locally defined MyStruct, which is defined(*) and constructed locally.

* I have no idea why the declaration of MyStruct is copied into the application's source files in the older applications, instead of just #including the header file from the DLL in which it is defined.  Maybe one of you do?

Thanks.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18770440
>>>> what would happen if I were to pass an array of structures please?
The dll would work with the old size of the struct. If you pass an array it is passed by giving the start address of the array and the number of elements (optionally). Obviously the dll will get wrong data when accessing elements with an index higher than 0.

>>>> it most likely will work
If passing a single instance of the new struct to the dll the first three members will have the same address relatively to the start address of the struct as if you would have passed an instance of the old  struct. So you always could cast a single pointer or reference to the old struct without having to fear that it goes wrong. The same concept is technically made for base classes and derived classes which share the same pointer (single inheritance only) cause the derived data members simply enhance the data members of the base class:

  [  base class members    ]
  [                                         derived members        ]

In C you have no inheritance but if you look at MyNewStruct you see how "inheritance" can be done in C, of course for data members only.

Regards, Alex
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18770512
>>>> So the old application will always pass an old structure
>>>> to the DLL, which is expecting a new structure
No, that definitively will not work. Your new dll needs to be able to find out whether it is called by an old or by a new application. You can achieve that by using some unused bits or members of the old struct and set a signature when it is passed from a new app. In your case it is very easy cause you can use the nSize member to signal whether you pass a new struct or an old one.  But never pass a new struct to an old dll having the size set to the new size. The old dll most likely would/should refuse the struct if doing so (at least my dll would do so)

    if (sizeof(MyStruct) != pms->nSize)    // wrong struct passed  
         exit(5);      // goodbye

Regads, Alex




0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18770570
>> I have never even considered that before.  Can you elaborate on "packed in the struct in exactly the same way" please?

The "packing rules" for structs are compiler- and system- dependent. On a 32-bit system, a given compiler might decide to align on 32-bit boundaries (leaving gaps between the data if needed) or not.
The only thing you can be sure of is that the data will be in the struct in the same order you defined them. Padding might be added between two data members of the struct, but never at the beginning of the struct.

So, if one DLL was compiled on system A with compiler C, and the other on system B with compiler D, there is no guarantee that the memory layout of the structs will be the same for both DLL's.

However, if both DLL's were compiled on the same system, with the same compiler, there shouldn't be a problem.


>> MY_DLL int GetInfo ( MyStruct* pMyStruct );

Ok, that's good. You might get away, by just adding the new data members at the end of the struct. Make sure that your DLL has a way of knowing whether it receives the old or the new struct. For example, the nSize data member might have a different value for the old and new struct.

See Alex's explanations for more info why this would most likely work.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 18770635
>> Obviously the dll will get wrong data when accessing elements with an index higher than 0.

Just to clarify: we are talking about passing an array of these structures *from* the DLL *to* the application; that would be the scenario relative to my original question.  So, I take it that your comment above would be the case if I were to add a new variable at index 1 (as my second example did in the original question).  Adding the new variables to the *end of* the structure declaration within the DLL would result in actually accessing the second element in the array when I believed I was accessing one of the new variables in the first element?  (EG attempting to access the 4th element (due to the *DLL's* declaration of the structure) in a struct that only has 3 elements (due to the *application's* definition of the structure) would mean overrunning the end of the first struct, and actually accessing memory in the second element in the array)?

Finally, are the elements in a structure accessed relative to their declaration order and the size of previous elements?  IE is the second element always at (address of struct) + sizeof ( first element ); the third element at (address of second element) + sizeof ( second element ) ?
0
 
LVL 19

Author Comment

by:mrwad99
ID: 18770687
Arghh, we have got out of sync with comments.

Alex:

>> No, that definitively will not work.

Are you referring to passing an old structure from the DLL to the app expecting a new structure, where the declaration of the new structure has the new variables *in the middle* (example 3 in my question), or where the new structure has new variables *at the end* (example 2 in my question) ?

Infinity08:

>> decide to align on 32-bit boundaries...

I have heard this kind of thing mentioned on MSDN (I think it is for functions like InterlockedExchanged or something similar) that quotes that variables must be aligned on 32 bit boundaries.  I have never known what it means.  Can you please explain?  (Points up to 350, as this is an additional question)
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 250 total points
ID: 18771184
>>>> we are talking about passing an array of these structures
case 1:   pass an array of new structure elements to an executable that expects an array of old structure elements:

sender:   [           ][           ][           ][           ]        
receiver  [       ][       ][       ][       ]

Definitively lost!

case 3:   pass an array of old structure elements to an executable that expects an array of new structure elements:

sender:   [       ][       ][       ][       ]      
receiver  [           ][           ][           ][           ]  

Definitively lost as well.

In case 2  the receiver can have both structs. After checking the nSize member of the first (!) element it can decide either to cast to new or to old struct.

     void funcInNewDll(struct MyStruct array[], int size)
     {
           MyNewStruct* newArray = NULL;
           bool  deleteArray = false;
           if (array[0].nSize == sizeof(MyNewStruct))
                  newArray = ( MyNewStruct*)array;   // ok it is a new array
          else
          {
                int i = 0;
                newArray = new MyNewStruct[size]; // malloc if C
                deleteArray = true;
                for { ; i < size; ++i)
                {
                     newArray[i] = *((MyNewStruct*)(&array[i])); // copy old data
                     newArray[i].newMember = ... ; // set some default for new members
                }
          }
          ...
          if (deleteArray)
              delete [] newArray;
     }

Regads, Alex
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18771360
>>>> case 3:  
of course it is case 2:

>>>> decide to align on 32-bit boundaries...

struct X
{
       char c;
       short s;
       char c2[2];
       int i;
};

Look at that struct. Assume we allocate new meory for it at the heap (new or malloc).

The heap manager allocates not single bytes but only chunks say of size 32, 64, 128, 256, 512, ... bytes  cause it would be too difficult to handle smaller pieces (and the memory got fragmented).

For our struct X we get a new 32 byte chunk which address is a multiple of 32 because there are no smaller pieces, say it is 0x00001024 to make it easy. Then our char member has the same address 0x00001024. What iis with member s. It could have 0x00001025. However, many compilers don't like it to have a 2-byte integer (short) at an odd address cause it must be moved to a 32bit register later and so on. So, the compiler decise to make alignment. It adds one extra byte after the c member and the s member has address 0x00001026. Then c2 starts at 0x00001028 - ok  already aligned - and the i member would get 0x0000100A. Here may happen the same thing as with the short. For integers the compiler prefers addresses which are a multiple of 4. A isn't a multiple of 4, so the i member was moved to 0x0000100C and two hidden bytes (fillers) were inserted between c2 and i.

That is called 32-bit alignment. You generally can avoid it by ordering your members  double, int, short, char or char arrays.

In our case alignment is no issue if no new compiler has come to play, cause the executables wouldn't have been properly aligned in the past as well what means tit never would have worked.

Regards, Alex

0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 250 total points
ID: 18771501
>>  Adding the new variables to the *end of* the structure declaration within the DLL would result in actually accessing the second element in the array when I believed I was accessing one of the new variables in the first element?

That is correct. Indexing in an array is done in jumps of size_of_array_element, so, the element at index i will be at address :

    array_base_address + i * size_of_array_element

So, if you send an array of struct A (with size 10 bytes for example), then the third element in the array will be at address :

    array_base_address + 2 * 10

But if the receiver expects an array of struct B (with size 8 for example), then when it tries to access the third element in the array, it will look for it at address :

    array_base_address + 2 * 8

which is not the correct address.


>> Finally, are the elements in a structure accessed relative to their declaration order and the size of previous elements?

Basically, yes. The order will be the same as how you defined the struct. Each struct member field will be at a certain offset from the base address of the struct.
However, it's important to know that that offset is not necessarily the sum of the sizes of the data before the current field. The compiler might have added padding (a block of memory that doesn't contain any relevant data) between the different struct fields.


>> IE is the second element always at (address of struct) + sizeof ( first element ); the third element at (address of second element) + sizeof ( second element ) ?

So, as I explained, this is not always the case. The second element might be at :

    (address of struct) + sizeof ( first element ) + padding_between_first_and_second_element

And the third element might be at :

    (address of struct) + sizeof ( first element ) + padding_between_first_and_second_element + sizeof ( second element ) + padding_between_second_and_third_element

Both padding values depend on the system and the compiler.



>> that quotes that variables must be aligned on 32 bit boundaries.  I have never known what it means.  Can you please explain?

Sure. Suppose you have a struct like this (I'm assuming a 32bit system) :

    struct test {
      unsigned char id[2];         // <--  2 bytes (16 bits)
      int age;                             // <--  4 bytes (32 bits)
      char gender;                    // <--  1 byte (8 bits)
      char *name;                     // <--  4 bytes (32 bits) (it's only a pointer)
    }

The compiler might decide to pack it like this :

    2 bytes : id                                     \ 4 bytes (32 bits)
    2 bytes : <padding>                       /
    4 bytes : age                                 > 4 bytes (32 bits)
    1 byte : gender                              \ 4 bytes (32 bits)
    3 bytes : <padding>                       /
    4 bytes : name                               > 4 bytes (32 bits)

Which would align the different fields to 32bit boundaries.

The compiler could also decide to do it like this :

    2 bytes : id
    4 bytes : age
    1 byte : gender
    4 bytes : name

without any padding (although that's less common).

Or like this :

    2 bytes : id                                    > 2 bytes (16 bits)
    4 bytes : age                                 > 4 bytes (32 bits)
    1 byte : gender                              \ 2 bytes (16 bits)
    1 byte : <padding>                         /
    4 bytes : name                               > 4 bytes (32 bits)

Or ...
0
 
LVL 19

Author Comment

by:mrwad99
ID: 18772211
Thank you both very much for the extended information given; it is appreciated.  The array discussion has bought some interesting issues to light.

To clarify overall:

When passing an individual old structure to the DLL, which expects a new structure, I am ok as long as the new variables are defined at the end of the structure, and not in the middle?  Correct ?


>> Or like this :

>> 2 bytes : id                                    > 2 bytes (16 bits)
    4 bytes : age                                 > 4 bytes (32 bits)
    1 byte : gender                              \ 2 bytes (16 bits)
    1 byte : <padding>                         /
    4 bytes : name                               > 4 bytes (32 bits)

But the first variable is 16 bits; not 32!  Or have I missed the point?  By 32 bit boundaries, I thought you meant that each variable must take 32 bits...

Thanks again.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18772520
>>>> Or have I missed the point?
Infinity's last sample obviously only should say that it is the compiler's business and not your's ;-)
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18772556
>>>>  I am ok as long as the new variables are defined at the end of the structure
Yes, but it is still a hack. And if you forgot about it in some years or someone else has to maintain the code it may go wrong then. You can use the MyNewStruct as I showed above and it is not beautiful but safe.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18772587
>> When passing an individual old structure to the DLL, which expects a new structure, I am ok as long as the new variables are defined at the end of the structure, and not in the middle?  Correct ?

If it's working today with the old structs, then it SHOULD work if you do what you said. However, you should still test it, because it's not guaranteed to work (although chances are high).


>> But the first variable is 16 bits; not 32!  Or have I missed the point?  By 32 bit boundaries, I thought you meant that each variable must take 32 bits...

The compiler does not HAVE to align each member field on 32bit boundaries. Certain compilers on certain systems will do so, but others will do it differently.

All of that doesn't matter much if you compile both DLL's with the same compiler on the same system. In any other case, you'll have to test whether it works.


And a bit more on this example :

    2 bytes : id                                    > 2 bytes (16 bits)
    4 bytes : age                                 > 4 bytes (32 bits)
    1 byte : gender                              \ 2 bytes (16 bits)
    1 byte : <padding>                         /
    4 bytes : name                               > 4 bytes (32 bits)

This one aligns the member fields on 16bit boundaries, and the entire struct is a multiple of 32bits.

To find out what your compiler does, try this code :

    typedef struct _MyStruct {
      UINT u;
      int nSize;
      WCHAR* pName;
    } MyStruct;


    typedef struct _MyStructNew {
      UINT u;
      int nSize;
      WCHAR* pName;
      DWORD dwNewParam;      // New
      WCHAR* pNewParam;      // New
    } MyStructNew;

    MyStruct test = { 0xAAAAAAAA, 0x77777777, 0x33333333 };
    cout << "size of MyStruct : " << sizeof(test) << " bytes" << endl;
    for (int i = 0; i < sizeof(test); ++i) {
      cout << hex << (unsigned int) *(((unsigned char*) &test) + i) << " ";
    }
    cout << endl;

    MyStructNew testNew = { 0xAAAAAAAA, 0x77777777, 0x33333333, 0x55555555, 0x66666666 };
    cout << "size of MyStructNew : " << sizeof(testNew) << " bytes" << endl;
    for (int i = 0; i < sizeof(testNew); ++i) {
      cout << hex << (unsigned int) *(((unsigned char*) &testNew) + i) << " ";
    }
    cout << endl;

It should output something like :

    size of MyStruct : 12 bytes
    AA AA AA AA 77 77 77 77 33 33 33 33
    size of MyStructNew : 20 bytes
    AA AA AA AA 77 77 77 77 33 33 33 33 55 55 55 55 66 66 66 66

If that's the output you get, then it's very probable that the new struct will work, as long as you pass only one struct (so, no array) by pointer.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18772786
Infinity, did you drink too much beer?

>>>> And a bit more on this example :
Noone will elaborate that sample?

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18772868
>> Infinity, did you drink too much beer?
Probably, because I don't get it heh. What do you mean ?

This is how I elaborated :
>> This one aligns the member fields on 16bit boundaries, and the entire struct is a multiple of 32bits.

It's not much, but it's something heh :)
0
 
LVL 19

Author Comment

by:mrwad99
ID: 18772906
Alex/Infinity08:

Thanks for the clarification on my first question; I now fully understand, which is good.

Infinity08:

I appreciate the time you are spending in giving long examples :)

Sadly the code you gave me fails to compile (VS 2005):  It does not like trying to assign 0x33333333 to a WCHAR*. ?!?

Can you please explain what this code shows?  I have looked at it but the penny still has not dropped...

Also, I mentioned above that MSDN states that for some functions, the variables passed to them *must* be aligned on 32 bit boundaries.  The examples I have seen here seem to show that the aligning is down to the compiler - how can we *force* the 32 bit alignment hence?

Thanks again.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18772963
>>>> I appreciate the time you are spending in giving long examples :)
Cheers!   ;-)

Use

MyStruct test = { 0xAAAAAAAA, 0x77777777, (WCHAR_T*)0x33333333 };
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18772970
Aaaah, it is  (WCHAR*)
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18772987
>> Sadly the code you gave me fails to compile (VS 2005):  It does not like trying to assign 0x33333333 to a WCHAR*. ?!?

Try adding a cast before the 0x33333333 like this :

    (WCHAR*) 0x33333333


>> Can you please explain what this code shows?  I have looked at it but the penny still has not dropped...

It was just in case you were interested to know what your dompiler does with your structs. It creates the struct with easily recignisable values (0xAAAAAAAA for example is easily visible in a memory dump). And it then dumps the memory occupied by the struct, to see how the compiler placed the data inside the struct.


>> The examples I have seen here seem to show that the aligning is down to the compiler - how can we *force* the 32 bit alignment hence?

If your compiler doesn't align on 32bit boundaries, and the function you want to call needs that, then you can add your own padding like this :

    struct test {
      unsigned char id[2];         // <--  2 bytes (16 bits)
      unsigned char padding1[2]  // <--- add two bytes of padding manually
      int age;                             // <--  4 bytes (32 bits)
      char gender;                    // <--  1 byte (8 bits)
      unsigned char padding2[3]  // <--- add three bytes of padding manually
      char *name;                     // <--  4 bytes (32 bits) (it's only a pointer)
    }

Note that this is not very pretty, and should only be done if there is no other way to do what you want, and if you know what you're doing.
Best is to just find a compiler that does align on 32bit boundaries in these cases.

Just to make sure : this has nothing to do with the original problem - it is just elaboration on the subject of struct alignment.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 18773515
>>>> I appreciate the time you are spending in giving long examples :)

>>Cheers!   ;-)

Sorry Alex, that comment by me should have been in the Alex/Infinity08 section.  I am sure you knew that anyway :)

OK I have made those changes and ran the code; the output I get from VS 2005 is

size of MyStruct : 12 bytes
aa aa aa aa 77 77 77 77 33 33 33 33
size of MyStructNew : 14 bytes
aa aa aa aa 77 77 77 77 33 33 33 33 55 55 55 55 66 66 66 66

This is not what you get Infinity08.  Is this bad?

From http://msdn2.microsoft.com/en-us/library/ms683609.aspx (InterlockedExchangePointer), the dox state that "On a 32-bit system, the parameters are 32 bits and must be aligned on 32-bit boundaries.".  So, Infinity08, you stated above

>> And a bit more on this example :

    >> 2 bytes : id                         > 2 bytes (16 bits)
    >> 4 bytes : age                        > 4 bytes (32 bits)
    >> 1 byte : gender                      \ 2 bytes (16 bits)
    >> 1 byte : <padding>                   /
    >> 4 bytes : name                       > 4 bytes (32 bits)

>> This one aligns the member fields on 16bit boundaries, and the entire struct is a multiple of 32bits.

so how can we tell if the structure as a whole is aligned on 32 bit boundaries?  

>> "and the entire struct is a multiple of 32bits."

Is that the answer?

I take it that if I was dealing with a pointer to a primitive type like an int, char or double, they would be fine, as they are factors of 32 in size?  Or not?

Points now at 500.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18773790
>> This is not what you get Infinity08.  Is this bad?

It's the same as what I posted, except for the "14 bytes" of the second struct ... but I assume that was an inconsistency in the code you used, because just after that it's correctly using 20.

Anyway, it's not bad at all !! It's what I expected, so it's good :)


>> so how can we tell if the structure as a whole is aligned on 32 bit boundaries?

By showing a memory dump in a similar way as I did earlier.


>> >> "and the entire struct is a multiple of 32bits."
>> Is that the answer?

No, that was just an observation. That COULD be a way that a certain compiler on a certain system implements it. It's just an example ...


>> I take it that if I was dealing with a pointer to a primitive type like an int, char or double, they would be fine, as they are factors of 32 in size?  Or not?

a char is 1 byte. An int is usually the word size of the system (ie. 4 bytes on a 32bit system). A double is usually double that (ie. 8 bytes on a 32bit system).

Notice that I used "usually" a few times. That's because different systems and compilers can use different sizes for the basic types.

So, if you're passing information between different applications, you still have to make sure that the type sizes are the same (especially if those applications are running on different systems). A simple sizeof() can already tell you a lot.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18778269
MyStruct and MyStructNew both have only integer and pointer types. So alignment is no issue if the types sizes were equal. You must make sure that source and target system have same sizes for DWORD (unsigned int), int, and WCHAR* (pointer size). If so, you can forget that issue.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 18806764
Right.

Firstly apologies for the late reply; I have been away from one machine and had to reinstall Windows on the machine I did have, hence I have been offline since last week.  That is all resolved now.

I am closing this now; I do have more questions but do not wish to flog this one as the original query has been resolved.  When I confirm my questions are relevant, I will post a link here to the new questions.

Thanks very much both, the help given here is greatly appreciated.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now