Solved

Threads = crash

Posted on 1998-08-30
34
359 Views
Last Modified: 2013-12-14
Quick background:
Using Windows 95 OEM 2 and Visual C++ Enterprise v. 5.0
Some MFC involved.  Mostly regular C++.

Hello everyone,

I am writing a game.  It is a simple game that takes place in outer space.  There are ships that shoot at each other using "torpedos" (actually just little dots :-).

So when the torpedo explodes, it executes this code:

void CTorp::ExplodeTorpedo (void)
{ m_TorpExpParams->m_PosX = m_PosX; // 0 - 1152 type double
  m_TorpExpParams->m_PosY = m_PosY; // 0 - 864 type double
  m_TorpExpParams->m_Wnd = m_Wnd; // Is a valid window.
  m_TorpExpParams->m_Number = 256; // unsigned int

  AfxBeginThread (ExplodeTorpedoThread,  // function (thread)
                  m_TorpExpParams, // parameter
                  THREAD_PRIORITY_NORMAL, // This thing isn't crucial
                  1024);  // How much stack is needed anyway?  Could this affect anything?
}

UINT ExplodeTorpedoThread (LPVOID param)
{ TorpedoExplosionParameters *fs = (TorpedoExplosionParameters *) param;
  struct FireWork
  { double x, y;
    double px, py;
    double speedx, speedy;
    COLORREF color, prevcolor;
  } *points;

  WORD i, gov;
  points = new FireWork [fs->m_Number]; // Fireworks :-)
  // I have 128mb RAM so the likely hood of that being 0 is
  // slim.
  for (i = 0; i < fs->m_Number; i++)
  { points[i].x = fs->m_PosX + drand (0, 5) - drand (0, 5);
    points[i].y = fs->m_PosY + drand (0, 5) - drand (0, 5);
    points[i].px = 0.0;
    points[i].py = 0.0;
    points[i].speedx = (double) (drand (0, 10000) - drand (0, 10000)) / 10000.0;
    points[i].speedy = (double) (drand (0, 10000) - drand (0, 10000)) / 10000.0;
    points[i].color = RGB (255, 255, 255);
    points[i].prevcolor = 0;
  }

  CDC *dc; // Some MFC in here.
  int r, g, b;
  dc = fs->m_Wnd->GetDC ();

  for (gov = 0; gov < 100; gov++) // Has to end sometime.
  { for (i = 0; i < fs->m_Number; i++)
    { points[i].prevcolor = dc->GetPixel ((WORD) points[i].x, (WORD) points[i].y); }

    for (i = 0; i < fs->m_Number; i++)
    { dc->SetPixel ((WORD) points[i].x, (WORD) points[i].y, points[i].color); }

    for (i = 0; i < fs->m_Number; i++)
    { points[i].px = points[i].x;
      points[i].py = points[i].y;

      points[i].x += points[i].speedx;
      points[i].y += points[i].speedy;

      r = GetRValue (points[i].color) - 5;
      g = GetGValue (points[i].color) - 5;
      b = GetBValue (points[i].color) - 5;

      if (r < 0)
      { r = 0; }
      if (g < 0)
      { g = 0; }
      if (b < 0)
      { b = 0; }

      points[i].color = RGB (r, g, b);
    }

    Sleep (50);

    for (i = 0; i < fs->m_Number; i++)
    { dc->SetPixel ((WORD) points[i].px, (WORD) points[i].py, points[i].prevcolor); }
  }

  fs->m_Wnd->ReleaseDC (dc);

  delete [] points;
  return 0;
}

But now for the strange part.  If this is code is still running when I exit the program, it will OCCASIONALLY crash.  Not always, but sometimes.  It will display this message (in case it's relevent):
GRAV caused an invalid page fault in
module GRAV.EXE at 024f:00407cee.
Registers:
blah blah blah

The address that it crashes at is the same all the time.  Now, normally I could probably figure this out, but I am not very fluent with the debugger.  Also, the window that pops up telling me that information contains the debug button which would normally help solve the problem.  BUT, the program has already exited, so pressing the debug button does nothing.

Any ideas (aside from the bad style and design)?
0
Comment
Question by:jonjons
  • 16
  • 10
  • 7
  • +1
34 Comments
 

Author Comment

by:jonjons
ID: 1171587
Edited text of question
0
 

Author Comment

by:jonjons
ID: 1171588
Edited text of question
0
 
LVL 11

Expert Comment

by:alexo
ID: 1171589
>> I am not very fluent with the debugger.

Instruct the compiler to generate a MAP file.  Search it for addresses that are either equal or slightly less than xxxx:00407CEE (when xxxx can be any hex number).

>> Any ideas

Yes, do not exit the program while threads are running.  This is bad karma.

Create an array of thread handles corresponding to the running threads and WaitForMultipleObjects() on them before you exit (a thread handle acts like a synchronization object that becomes signalled when the thread terminates).
0
 
LVL 22

Expert Comment

by:nietod
ID: 1171590
I agree with everything alexo said.  In addition, one possible source for the crash is that in the ExplodeTorpedoThread(0 procedure you are using m_TorpExpParams from an object used in another thread.  You are not taking any precautions to syncronize access to this data and (more importantly) if the other thread is destroyed, I suspect this data is as well, yet the ExplodeTorpedoThread() will continue to use the data (likely cuplprit).
0
 
LVL 22

Expert Comment

by:nietod
ID: 1171591
>> points = new FireWork [fs->m_Number]; // Fireworks :-)
>> // I have 128mb RAM so the likely hood of that being 0 is

FYI new no longer returns a NULL pointer when it runs out of memory.  It now throws an exception instead.
0
 

Author Comment

by:jonjons
ID: 1171592
Responses:

alexo:
>> generate a map file
Good suggestion... but the file doesn't seem to contain any addresses even close to 00407CEE.

Here are some parts of the file:
------
 Preferred load address is 00400000

 Start         Length     Name                   Class
 0001:00000000 00008aafH .text                   CODE
 0001:00008ab0 0000132dH .text$x                 CODE
 0002:00000000 0000081eH .rdata                  DATA
 0002:00000820 00000560H .xdata$x                DATA
 0002:00000d80 00000000H .edata                  DATA
 0003:00000000 00000104H .CRT$XCA                DATA
 0003:00000104 00000104H .CRT$XCL                DATA
 0003:00000208 00000104H .CRT$XCU                DATA
 0003:0000030c 00000104H .CRT$XCZ                DATA
 0003:00000410 00000104H .CRT$XIA                DATA
 0003:00000514 00000104H .CRT$XIZ                DATA
 0003:00000620 00000940H .data                   DATA
 0003:00000f60 00000140H .bss                    DATA
 0004:00000000 00000078H .idata$2                DATA
 0004:00000078 00000014H .idata$3                DATA
 0004:0000008c 0000049cH .idata$4                DATA
 0004:00000528 0000049cH .idata$5                DATA
 0004:000009c4 0000031bH .idata$6                DATA
 0005:00000000 00000370H .rsrc$01                DATA
 0005:00000370 000010f9H .rsrc$02                DATA

  Address         Publics by Value              Rva+Base     Lib:Object

 0001:000003a0       ??0CGetData@@QAE@PAVCWnd@@@Z 004013a0 f   GetData.obj
 0001:00000466       ?DoDataExchange@CGetData@@MAEXPAVCDataExchange@@@Z 00401466 f   GetData.obj
 0001:0000052e       ?_GetBaseMessageMap@CGetData@@KGPBUAFX_MSGMAP@@XZ 0040152e f   GetData.obj
 0001:00000538       ?GetMessageMap@CGetData@@MBEPBUAFX_MSGMAP@@XZ 00401538 f   GetData.obj

.

 0004:00000944       __imp__hypot               0040e944     msvcrtd:MSVCRTD.dll
 0004:00000944       __imp___hypot              0040e944     msvcrtd:MSVCRTD.dll
 0004:00000948       __imp___setmbcp            0040e948     msvcrtd:MSVCRTD.dll
 0004:0000094c       \177MSVCRTD_NULL_THUNK_DATA 0040e94c     msvcrtd:MSVCRTD.dll
 0004:0000098c       __imp__IsWindow@4          0040e98c     user32:USER32.dll
 0004:00000990       __imp__MessageBeep@4       0040e990     user32:USER32.dll
 0004:00000994       __imp__GetSystemMetrics@4  0040e994     user32:USER32.dll
 0004:00000998       \177USER32_NULL_THUNK_DATA 0040e998     user32:USER32.dll

 entry point at        0001:000075b0
---------
As you can see, the addresses are all considerably lower than 00407CEE.

>> Create an array of thread handles ...
That sounds like an even better idea.  It will take me a little while to implement since I'm not a pro at programming, but I'll get back to you on its result.

nietod:
No other functions/processes use the data in m_TorpExpParams.  The class CTorp allocates the memory in the constructor and de-allocates it in the destructor.

You know, as I was typing that, I think I realized the problem.  When the program exits, the destructor is called for most everything at program termination, right?  Including the CTorp object?  If that's the case, the memory was probably freed, and the thread continued to use it.

I suspect implementing alexo's idea will solve the problem if that's the case.

Any other thoughts?
0
 

Author Comment

by:jonjons
ID: 1171593
Also,

>> FYI new no longer returns a NULL pointer ...

I am pretty new to programming in windows.  I used to use a very old compiler for DOS.  I guess that makes for a lot of extra code in my programs!  Thanks for telling me that.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1171594
>> You know, as I was typing that, I think I realized the problem.  When the
>> program exits, the destructor is called for most everything at program
>> termination, right?  Including the CTorp object?  If that's the case,
>> the memory was probably freed, and the thread continued to use it.

It depends on your design.  But this is likely to be your problem, that is why I sugggested it.

>> I suspect implementing alexo's idea will solve the problem if that's the case.
That and other potential problems.

>> >> generate a map file
>>  Good suggestion... but the file doesn't seem to contain any
>> addresses even close to 00407CEE.
That address may be for a procedure in the run-time library that your program called and that subsequently crashed due to parameters passed to it.
0
 

Author Comment

by:jonjons
ID: 1171595
Wow, I solved it using a pretty lame method that works:

void CTorp::ExplodeTorpedo (void)
{ TorpedoExplosionParameters *Params = new TorpedoExplosionParameters;

  Params->m_PosX = m_PosX;
.

UINT ExplodeTorpedoThread (LPVOID param)
{ TorpedoExplosionParameters *fs = (TorpedoExplosionParameters *) param;

.
  delete [] points;
  delete fs;
  return 0;
}

Hehee, how's that? :-)
0
 
LVL 22

Expert Comment

by:nietod
ID: 1171596
That will work in this instance.  But this change doesn't protect you from having it happen in other cases, thus be prepared to imploy the same sort of logic in other cases.  
0
 

Author Comment

by:jonjons
ID: 1171597
Actually, I had another case like this (when the "star-ship" blows up), but after you suggested what might be happening, it finally dawned on me that I had done it wrong.

Since alexo showed me how to do it using a different method, the method that I should probably use in the future, I am going to delete this question and split the points between you and alexo (150 and 50 would probably be fair).

I will wait for acknowledgement from both of you before I delete it and post two fake questions.

Thanks again!
0
 

Author Comment

by:jonjons
ID: 1171598
Or is this question in fact worth 200 points?  It seemed almost impossible at the time, would it be alright if I decreased the points to say 125 (nietod) and 35 (alexo)?
0
 
LVL 11

Expert Comment

by:alexo
ID: 1171599
>> FYI new no longer returns a NULL pointer when it runs out of memory.  It now throws an exception instead.
That is what the standard mandates.  However, older compiler will not suddenly start generating different code because the C++ standard was accepted...

>> Or is this question in fact worth 200 points?
That is up to you to decide.  However, don't delete it just yet because I'd like to give you some "rules" for mutithreading and I'm sure Todd can add too.

First, as Todd mentioned, it is very risky to allow several threads to access the same resource simultaneously.  In particular, when a thread modifies the resource, no other thread should be accessing it.  This can be ensured by using EnterCriticalSection() and friends.  There are other synchronization objects (mutexes, semaphores, events, etc.) which are more versatile but nothing beats critical sections for efficiency.

Second, note that when a thread waits on an object or a CS (or just Sleep()s), it consumes almost no CPU time.  Try to put to sleep or block a thread when it has nothing useful to do.

Third, as I mentioned before, don't leave running threads.  Try to WaitForMultipleObjects() for all threads to finish.  Provide a mechanism to notify the threads that the user requested to abort the program (event objects are particularly suited for that).

0
 

Author Comment

by:jonjons
ID: 1171600
Okay, I will not delete it until you both give me the okay.

Thank you for the information you have provided me with, alexo.  I will keep that in mind for in the future and with this project.  I am new to multithreading so your information has helped.  Thanks!
0
 
LVL 22

Expert Comment

by:nietod
ID: 1171601
>> However, older compiler will not suddenly start generating different
>> code because the C++ standard was accepted..
Why not, whats the point in having the standard?  : - )  (that was joke)   He is using VC5.  VC5 throws an exception.

I agree with what alex has to say on all of the above.  To make it more concrete, I suspect you have many cases where a thread executes a task and sleeps a specifc time and then repeats.  Rather then sleeping, use WaitForMultipleObjects were the wait time is the time you used to sleep and where the object you want for is an event that another thread can signal to indicate that the waiting thread should terminate.

who gets the points is up to you, but you can't decrease the point value of this question.  However, I would have no objections if you gave them to alex as he was here first.
0
 

Author Comment

by:jonjons
ID: 1171602
>> I suspect you have many cases where a thread executes a task
>> and sleeps a specifc time and then repeats

Actually, these threads are all created on the fly.  All are just temporary and will end after about 10 seconds of execution.  They do in fact end after awhile because I loaded up "Process Viewer" and kept hitting the refresh button.  My program would sometimes have 5 or 6 threads when there was a lot of activity, but other times only 1 (the program's main thread).
0
 

Author Comment

by:jonjons
ID: 1171603
>> who gets the points is up to you, but you can't decrease the
>> point value of this question.  However, I would have no
>> objections if you gave them to alex as he was here first.

I just want to give the right number of points to both of you since you both have helped me solve my problem and future problems I would have no doubt had.
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 22

Expert Comment

by:nietod
ID: 1171604
About my point on the sleeping threads, though.these threads have the same sort of design don't they?  They last for a seconds, but during those seconds they are in a loop that has them do a quick action and then sleep a while.  If you change to using WaitForSingleObject() instead of sleep() you can cause those threads to abort early, before their time is up.
0
 

Author Comment

by:jonjons
ID: 1171605
Ahhhh.... I see what you mean now, I was reading it wrong.  But after reading the documentation on the function, I am at a loss as to how to actually use it.  It wants a handle to an object plus a time out value.

Can you show me how to integrate it with what I have already?

Thank you very much.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1171606
I'll give you an outline.  I've used it once a few years ago.  I'm no expert.  But if you plan on using multi-threading you will need to be.

Use CreateEvent() to create an event that will indicate if a thread should termiante early.  You will store the handle returned by createevent () in the list of thread's alex proposed.  That way you can use the handle to abort the currently running threads.  When you create the event you want to create it unsignaled, you don't need to worry about the reset option, and it doesn't need a name, thus you would use "CreateEvent(NULL,TRUE,FALSE,NULL)"

This event object handle would be passed to the thread so it can wait on it when it needs to sleep.  Now when its needs to sleep it uses WaitForSingleObject() (You could use WaitForMultipleObjects(), but you only have one object, so this is easier.)  You will specify a handle to the event object you want to wait for and a timeout time that you used to sleep for.  The wait function will return for one of two reasons.  If the timeout expired, it will return WAIT_TIMEOUT.  In that case just perform your work and go to sleep again.  If the thread is being aborted, then the object will be signaled and the procedure will return WAIT_OBJECT_0.  In this case, take what actions are needed to abort the thread.  

it would look a little like

 for (gov = 0; gov < 100; gov++) // Has to end sometime.
{
    /// do work.
   if (WaitForSingleObject(EvtObjHnd,50) == WAIT_TIMEOUT)
     break; // abort this loop.
 }

Now when you want to abort a thread you retreive the event object handle for the thread and use SetEvent().  This will signal the event and cause the wait to end.  The thread will terminate soon after.  (You still need to wait until the thread terminates before you can let the main thread terminate.)

One more thing, when ever a thread terminates,  you close the handle on the event object you created for it.  (Or reuse the event for a new thread.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1171607
>> Actually, these threads are all created on the fly.  All are just temporary and will end after about 10 seconds of execution.

This is the wrong approach.  Creating and destroying threads are very computationally intensive operations (you can test that by writing a loop that creates threads that exit immediately, waits for them to exit and iterates).

A better solution is to have a pool of pre-created threads that wait on events and perform some processing when awakened.

Now, about the points:
I'm sure this discussion is (or will be) worth the 200 points.  The question who gets them can be easily solved.  You can give them to one of us and ask Linda (from customer support) to give the same amount to the other one.  It is common practice in such cases and it will be a shame to lose such a good thread.

The bad news are that Todd will be unavailable for a week or so.  The good news are that I have mostly recovered from a disk crash...
0
 
LVL 11

Expert Comment

by:alexo
ID: 1171608
>> Actually, these threads are all created on the fly.  All are just temporary and will end after about 10 seconds of execution.

This is the wrong approach.  Creating and destroying threads are very computationally intensive operations (you can test that by writing a loop that creates threads that exit immediately, waits for them to exit and iterates).

A better solution is to have a pool of pre-created threads that wait on events and perform some processing when awakened.

Now, about the points:
I'm sure this discussion is (or will be) worth the 200 points.  The question who gets them can be easily solved.  You can give them to one of us and ask Linda (from customer support) to give the same amount to the other one.  It is common practice in such cases and it will be a shame to lose such a good thread.

The bad news are that Todd will be unavailable for a week or so.  The good news are that I have mostly recovered from a disk crash...
0
 
LVL 22

Expert Comment

by:nietod
ID: 1171609
I'm here for another few hours.

>> Creating and destroying threads are very computationally intensive
>> operations (you can test that by writing a loop that creates threads
>> that exit immediately, waits for them to exit and iterates)

I had a feeling it was a bad idea too, but didn't have any facts to back it up.  I'm glad you said that.

 In addition, if the thread spends most of its time asleep (I don't know if this is the case or not) you might not need the thread.  You might be able to do its work in the main thread by setting a timer  (regular timer or multi-media timer) and then check for work to be done on each timer message.  Historically most games used (use?) this technique as most games weren't implimented on multi-processing OSs.
0
 

Author Comment

by:jonjons
ID: 1171610
Sorry I couldn't have gotten back a little sooner...

nietod - I will implement your changes once I get the list of threads worked out.  Since you are apparently going to be out of town, that shouldn't be a problem :)

>> Creating and destroying threads are very
>> computationally intensive operations
This game doesn't need to do much, if you saw it, you'd see what I mean.  It will also never be distributed to any computer lower than a Pentium 233.  But I suppose that is correct.

About the list of running threads you proposed, how do you recommend I create/maintain such a list?  If you know any MFC, could you recommend a class that would help?  I suppose it would probably be best to write my own, or just create an array of thread handles plus an array of bools indicating which ones are valid at the time.  Then as the thread ended, the arrays could be updated accordingly.

I have modified the functions that start the threads to return the pointer to the CWinThread object associated with the thread (CWinThread is an MFC class).  The handle to the thread is also readily accessable.

Also, about the points, since I am getting them daily, I will make sure that you and nietod get the number you deserve.  It may not be today or tomorrow, but sometime.
0
 

Author Comment

by:jonjons
ID: 1171611
I think that is right, I probably do not even need the other threads.  I was actually just trying them for the first time.  This whole project is just for fun as you could imagine.

I didn't particularily want to use the timer approach though.  With all that code plus all the code for another "explosion" in the function responding to the timer would be an awful lot (i.e. convoluted).
0
 
LVL 22

Expert Comment

by:nietod
ID: 1171612
>> didn't particularily want to use the timer approach though.  With all that code
>> plus all the code for another "explosion" in the function responding to the
>>timer would be an awful lot (i.e. convoluted).
its not so bad.  Typically you would just maintain a list of tasks to be performed and the times at which they should next be performed.  This should be quite a bit easier in C++ (I did it in assembly).  

Create a base class that represents a "task"  Create a virtual function that instructs the object to do a step in the task (Like move a torpedo 1 unit).  
Then derive classes from it for the different tasks you need to accomplist, like move torpedo, expand explostion, move ship etc.  In each of these classes write overides for the virtual function so they class does the work it is intended to do.  

Now when a task needs to be done, An object for the task is created (along with its necessary parameters, like the torpedo location)  Then a pointer to the  task object is placed in a linked list along with an entry that says when it next needs to be run.  Every timer tick, you scan the list for entries that need to go to work and call their virtual functions.   Here's a nice idea.  Have the virtual function return either the time that it should be called again or a 0 to indicate that the task is done and should be deleted.  (The base class needs a virtual destructor for this).

0
 

Author Comment

by:jonjons
ID: 1171613
Sorry that I couldn't have gotten back a little sooner... busy, busy, busy.

Anyhow, after reading nietod's above post, I think I might be in a little over my head :-)  Perhaps in the future I will try multithreading again.

Like I said, I am certainly not a professional at this.  Programming is just a hobby.

What to do with the points?  Should one of you answer this and then the other can take the question that linda will ask?  Is that how it will work?  What section do I ask to have another question posted worth the same number of points?  Thanks, I am new to EE too!
0
 
LVL 11

Expert Comment

by:alexo
ID: 1171614
>> This game doesn't need to do much [...]
It will allow you to practice multithreaded programming and teach you some of the important principles involved.

>> If you know any MFC, could you recommend a class that would help?
I try to avoid MFC whenever possible.

>> I suppose it would probably be best to write my own
Of course.  Since this is for educational purposes it will allow you to understand things on a deeper level.  You can use a library (even MFC... yech!) for "commercial" code.

>> or just create an array of thread handles plus an array of bools indicating which ones are valid at the time.
Something like that.  You can write a dispatcher class that will manage the thread allocation.

>> Then as the thread ended, the arrays could be updated accordingly.
When a thread finishes processing it can wait on an event.  Only one of the waiting threads will be released when the event is signalled.

>> It may not be today or tomorrow, but sometime.
No hurry.  The points are virtual anyway.  The "experts" get no real compensation.  You can say the points are the EE equivalent to flowers with a "thank you" note.

>> I am certainly not a professional at this.  Programming is just a hobby.
Get a good book.  Petzold's is usually recommended for Win32 beginners.

>> What to do with the points?  [...]
The EE engine is quite limited as to what it can do.  If you want something different, you ask customer support.  For example, expert A locks the question and gets the points, then you post a 0-point question to the EE customer support area (http://www.experts-exchange.com/topics/bin/NewQForm?ta=4) addressed to Linda (in the title) saying something like "Experts A and B both contributed to Q.10076476.  Since I gave the points to A, will it be possible for you to offer the same amount to B?  Thank you".  This is not a standard but it works.
However, if you have enough points of your own, it is customary to post a dummy question yourself (titled "for expert B only", containing "for your help on Q.10076476").

0
 

Author Comment

by:jonjons
ID: 1171615
Thank you for all of your input.  I will try to get a copy of that book you mentioned sometime.  Can you please post an answer so you can get the 220 points?  I will then post a question in the customer service area and ask for the same number of points for nietod.
0
 
LVL 11

Accepted Solution

by:
alexo earned 220 total points
ID: 1171616
If you have further questions don't hesitate to ask.
0
 
LVL 7

Expert Comment

by:linda101698
ID: 1171617
alexo has posted an answer to this question.  You can now grade this question giving alexo the points.

Great cooperation on this question alexo and nietod :-)

Look in the new questions for a question directed to you nietod!

Linda Gardner
Customer Service @ Experts Exchange
0
 
LVL 11

Expert Comment

by:alexo
ID: 1171618
>> Great cooperation on this question alexo and nietod
Hey Todd, shall we start our own company?
0
 
LVL 22

Expert Comment

by:nietod
ID: 1171619
An international company?  Not a chance.  I can't figure out my taxes as it is.
0
 

Author Comment

by:jonjons
ID: 1171620
You two should start your own company... You could probably do pretty well!  Private consultation or something like that.

Thanks for the help everyone!
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

Suggested Solutions

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Programmer's Notepad is, one of the best free text editing tools available, simply because the developers appear to have second-guessed every weird problem or issue a programmer is likely to run into. One of these problems is selecting and deleti…
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

708 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