HEAP Corruption Error

Please support our C++ advertiser: Programming Forums - DaniWeb Sister Site
Thread Solved

Join Date: Dec 2007
Posts: 226
Reputation: henpecked1 is an unknown quantity at this point 
Solved Threads: 1
henpecked1 henpecked1 is offline Offline
Posting Whiz in Training

HEAP Corruption Error

 
0
  #1
Mar 14th, 2008
I'm trying to calculate the length of three individual arrays and plug that length into a function to dynamically allocate memory to a new array and delete it. I keep overwriting my HEAP and I'm not sure where the problem is

  1. void punchmeinthehead()
  2. {
  3. const int maxin = 16;
  4. char lastName[maxin] ;
  5. char firstName[maxin] ;
  6. char midName[maxin] ;
  7.  
  8. size_t length = strlen(lastName) + strlen(firstName) + strlen(midName) + 1;
  9. char *fullName = new char[length];
  10. strcpy (fullName, lastName);
  11. strcat (fullName, " ");
  12. strcat (fullName, firstName);
  13. strcat (fullName, " ");
  14. strcat (fullName, midName);
  15. cout << fullName << endl;
  16. delete [] fullName;
  17. }

Main looks like this

  1. void main()
  2. {
  3. const int maxin = 16;
  4. char lastName[maxin];
  5. char firstName[maxin];
  6. char midName[maxin];
  7.  
  8.  
  9. getlast(lastName, maxin);
  10. getfirst(firstName, maxin);
  11. getmid(midName, maxin);
  12. punchmeinthehead();
  13.  
  14. }

The calling functions look like this

  1.  
  2. void getlast( char lastName[] , int maxin)
  3. {
  4. cout << " Please enter your last name up to 15 characters " << endl;
  5. cin.getline(lastName, maxin, '\n' );
  6. cin.ignore (cin.rdbuf()->in_avail(), '\n');
  7.  
  8. }
  9.  
  10.  
  11. //Input first name
  12. void getfirst( char firstName[] , int maxin)
  13. {
  14. cout << " Please enter your first name up to 15 characters " << endl;
  15. cin.getline(firstName, maxin, '\n' );
  16. cin.ignore (cin.rdbuf()->in_avail(), '\n');
  17.  
  18. }
  19.  
  20.  
  21. //Input middle name
  22. void getmid( char midName[] , int maxin)
  23. {
  24. cout << " Please enter your middle name up to 15 characters " << endl;
  25. cin.getline(midName, maxin, '\n' );
  26. cin.ignore (cin.rdbuf()->in_avail(), '\n');
  27. }
Last edited by henpecked1; Mar 14th, 2008 at 2:16 am.
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 269
Reputation: sarehu is on a distinguished road 
Solved Threads: 22
sarehu's Avatar
sarehu sarehu is offline Offline
Posting Whiz in Training

Re: HEAP Corruption Error

 
0
  #2
Mar 14th, 2008
Originally Posted by henpecked1 View Post
  1. void punchmeinthehead()
  2. {
  3. const int maxin = 16;
  4. char lastName[maxin] ;
  5. char firstName[maxin] ;
  6. char midName[maxin] ;
  7.  
  8. size_t length = strlen(lastName) + strlen(firstName) + strlen(midName) + 1;
  9. char *fullName = new char[length];
  10. strcpy (fullName, lastName);
  11. strcat (fullName, " ");
  12. strcat (fullName, firstName);
  13. strcat (fullName, " ");
  14. strcat (fullName, midName);
  15. cout << fullName << endl;
  16. delete [] fullName;
  17. }
There are so many problems with this function. I don't know where to begin. Instead of answering your question, I would like to ask what you think the contents of lastName will be, and how you expect strlen(lastName) to behave.
Reply With Quote Quick reply to this message  
Join Date: Nov 2007
Posts: 981
Reputation: mitrmkar is just really nice mitrmkar is just really nice mitrmkar is just really nice mitrmkar is just really nice mitrmkar is just really nice 
Solved Threads: 210
mitrmkar mitrmkar is offline Offline
Posting Shark

Re: HEAP Corruption Error

 
0
  #3
Mar 14th, 2008
About the punchmeinthehead() function ...
  1. void punchmeinthehead()
  2. {
  3. const int maxin = 16;
  4. // Here you have three uninitialized arrays of char, use a
  5. // debugger to see what they contain here ...
  6. // (Shouldn't you instead be using the variables
  7. // that you have in your main() ?)
  8. char lastName[maxin] ;
  9. char firstName[maxin] ;
  10. char midName[maxin] ;
  11.  
  12. // if your three arrays are OK at this point, the following works
  13. size_t length = strlen(lastName) + strlen(firstName) + strlen(midName) + 1;
  14.  
  15. char *fullName = new char[length];
  16. // fullname may also be NULL at this point
  17. <snip>
  18. // Did you account for the extra space character when
  19. // allocating memory?
  20. strcat (fullName, " ");
  21. <snip>
  22. }

Hmm .. you could rename punchmeinthehead() to punchmeintheheap() ...
Last edited by mitrmkar; Mar 14th, 2008 at 7:12 am.
Reply With Quote Quick reply to this message  
Join Date: Dec 2007
Posts: 226
Reputation: henpecked1 is an unknown quantity at this point 
Solved Threads: 1
henpecked1 henpecked1 is offline Offline
Posting Whiz in Training

Re: HEAP Corruption Error

 
0
  #4
Mar 14th, 2008
To Sarehu: I'm aware there are problems with it, but I'm very new to this so I expected there to be plenty wrong.

Originally, I'm trying to prompt the user for last, first, and middle names, storing them in fixed arrays. Then, output that name by dynamically allocating a "new" array where the names are all added together with appropriate spaces. After that, prompt the user for another input or to quit, I just haven't written the loop portion yet because I can't get past this.

I had the fixed arrays and array size declared in the header, but my instructor nixed that idea and made me change it all around to pass the arrays in. Now this part I'm even worse at than writing original functions. So I try to pass the array contents in, but it gives me the unknown identifier errors and all that. When that happened, I put the variables in the function (since I can no longer use globals).

Strlen at this point I'm hoping to calculate the contents of the fixed arrays lastName, firstName, and midName, and then add the lengths together so I know how large the dynamic allocation has to be and pass it into the dynamically allocated array. Obviously that's not happening and I've screwed it up from my original design.

The original design (see henpecked1 post on string help) had the string length being done as a separate function and pass it into punchmeinthehead, but when the instructor changed it all around, I no longer knew the syntax for passing it, especially using the size_t identifier.

Is that clear enough or did I just confuse things more?
Last edited by henpecked1; Mar 14th, 2008 at 1:05 pm.
Reply With Quote Quick reply to this message  
Join Date: Dec 2007
Posts: 226
Reputation: henpecked1 is an unknown quantity at this point 
Solved Threads: 1
henpecked1 henpecked1 is offline Offline
Posting Whiz in Training

Re: HEAP Corruption Error

 
0
  #5
Mar 14th, 2008
To mitrmkar:

The uninitialized arrays are there because the program is making me identify the variables lastName, firstName, midName, and maxin. These are indeed the variables identified in main, unless you mean something that's obviously escaping me.

When I use the debugger and see what's in them, (as best I can being new) they pretty much contain the expected junk until the user enters a name, and then they contain the name.

I know I'm overwriting memory, and I believed it was because I wasn't passing the length properly, but if it's because the functions I created for user input are wrong, by all means, tell me what I did wrong because everything works fine up until the point of working with the dynamic allocation of the new array
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 269
Reputation: sarehu is on a distinguished road 
Solved Threads: 22
sarehu's Avatar
sarehu sarehu is offline Offline
Posting Whiz in Training

Re: HEAP Corruption Error

 
1
  #6
Mar 14th, 2008
Originally Posted by henpecked1 View Post
  1. void punchmeinthehead()
  2. {
  3. const int maxin = 16;
  4. char lastName[maxin] ;
  5. char firstName[maxin] ;
  6. char midName[maxin] ;
The problem here is that these aren't the same arrays that were declared in the main function. Just because they have the same name doesn't mean they will be the same arrays. In fact, they won't be.

The idea being that you don't want to have to keep track of what names have been given for variables in other parts of your program, C code sees the existence of a given variable only with that variable's block. If you write your punchmeinthehead function as the following, you'll get the same exact behavior. (Note that I've only changed the local names around.)

  1. void punchmeinthehead()
  2. {
  3. const int maxin = 16;
  4. char lastBlah[maxin] ;
  5. char firstBlah[maxin] ;
  6. char midBlah[maxin] ;
  7.  
  8. size_t length = strlen(lastBlah) + strlen(firstBlah) + strlen(midBlah) + 1;
  9. char *fullName = new char[length];
  10. strcpy (fullName, lastBlah);
  11. strcat (fullName, " ");
  12. strcat (fullName, firstBlah);
  13. strcat (fullName, " ");
  14. strcat (fullName, midBlah);
  15. cout << fullName << endl;
  16. delete [] fullName;
  17. }

The rule is, for any local variable you declare, if you change its name and all the instances of its name below that declaration in the same block, you won't change the behavior of your code. So hopefully, you can see that local variable declarations don't refer to anything outside the function, and that they define variables that last only during the current instance of the function call, and cease to exist after the function returns. Even if you have a function call itself, a different piece of memory will be used for each instance of the function call.

Now let's look at the other problem.

  1. size_t length = strlen(lastName) + strlen(firstName) + strlen(midName) + 1;
  2. char *fullName = new char[length];
  3. strcpy (fullName, lastName);
  4. strcat (fullName, " ");
  5. strcat (fullName, firstName);
  6. strcat (fullName, " ");
  7. strcat (fullName, midName);
  8. cout << fullName << endl;
  9. delete [] fullName;
  10. }
Now, you should see there that length is 2 less than what it should be, since you forgot to account for the two spaces you've included.

Let's look at how some of the other code works and why it's different than punchmeinthehead :

  1. void getlast( char lastName[] , int maxin)
  2. {
  3. cout << " Please enter your last name up to 15 characters " << endl;
  4. cin.getline(lastName, maxin, '\n' );
  5. cin.ignore (cin.rdbuf()->in_avail(), '\n');
  6.  
  7. }
There's your getlast implementation. And unlike punchmeinthehead , the way you've used it, the character buffer declared in main ends up getting modified. You should ask, why is that?

It has nothing to do with the name you've used. You could rewrite your getlast function with a different variable name:

  1. void getlast( char something[] , int maxin)
  2. {
  3. cout << " Please enter your last name up to 15 characters " << endl;
  4. cin.getline(something, maxin, '\n' );
  5. cin.ignore (cin.rdbuf()->in_avail(), '\n');
  6.  
  7. }
Why does that work? The question is: How does getlast see the character array in the calling function, main ? The answer is: You've passed the memory address of this character buffer directly, as a parameter.

When you write getlast(lastName, maxin); , you're passing two values, both of which are numbers. The first number, lastName , is the memory address of the character array that sits in the local memory of the current instance of the main function. That number is unintelligible, and we call it a character array, since that's how we mean to use it. The second number is 16, the value of maxin .

When this function call happens, getlast gets executed within its own area of local memory, and the variables something and mixin get assigned the values of the arguments you've passed. In this case, something will be assigned whatever value was passed as the first argument, and mixin will be assigned whatever walue was passed as the second argument. (Again, the fact that the main function has a variable called mixin can be treated like nothing more than a coincidence.)

So then getlast is performing operations with a memory address pointing to an array in the instance of the main function.

  1. cin.ignore (cin.rdbuf()->in_avail(), '\n');
It must be annoying, having to deal with crap like this as a newbie. There's something wrong with the teacher if you have to write magic like that.
Reply With Quote Quick reply to this message  
Join Date: Dec 2007
Posts: 226
Reputation: henpecked1 is an unknown quantity at this point 
Solved Threads: 1
henpecked1 henpecked1 is offline Offline
Posting Whiz in Training

Re: HEAP Corruption Error

 
0
  #7
Mar 14th, 2008
Okay, so the heap error is gone and I feel really stupid for missing the spaces, and as your explanation would impart, it's printing out 50 elements of crap to the screen. So now the question begs because I am new, how do those arrays get passed (syntax) to the punchmeinthehead function?

And he gave us the cin.ignore part, I didn't have to figure that out thank goodness. He tells us it is to clear any remnants left from the getline in a nice clean manner
Reply With Quote Quick reply to this message  
Join Date: Dec 2007
Posts: 226
Reputation: henpecked1 is an unknown quantity at this point 
Solved Threads: 1
henpecked1 henpecked1 is offline Offline
Posting Whiz in Training

Re: HEAP Corruption Error

 
0
  #8
Mar 14th, 2008
Main looks the same, and I moved punchmeinthehead to the same cpp file where the input functions are for ease of posting and printing. Here is what I have now:
  1. #include "nameinp.h"
  2. #include <iostream>
  3. #include <string.h>
  4. using namespace std;
  5.  
  6. //Input last name
  7. void getlast( char lastName[] , int maxin)
  8. {
  9. cout << " Please enter your last name up to 15 characters " << endl;
  10. cin.getline(lastName, maxin, '\n' );
  11. cin.ignore (cin.rdbuf()->in_avail(), '\n');
  12.  
  13. }
  14.  
  15.  
  16. //Input first name
  17. void getfirst( char firstName[] , int maxin)
  18. {
  19. cout << " Please enter your first name up to 15 characters " << endl;
  20. cin.getline(firstName, maxin, '\n' );
  21. cin.ignore (cin.rdbuf()->in_avail(), '\n');
  22.  
  23. }
  24.  
  25.  
  26. //Input middle name
  27. void getmid( char midName[] , int maxin)
  28. {
  29. cout << " Please enter your middle name up to 15 characters " << endl;
  30. cin.getline(midName, maxin, '\n' );
  31. cin.ignore (cin.rdbuf()->in_avail(), '\n');
  32. }
  33.  
  34. void punchmeinthehead()
  35. {
  36.  
  37. size_t length = strlen(getlast) + strlen(getfirst) + strlen(getmid) + 3;
  38. char *fullName = new char[length];
  39. strcpy (fullName, getlast);
  40. strcat (fullName, " ");
  41. strcat (fullName, getfirst);
  42. strcat (fullName, " ");
  43. strcat (fullName, getmid);
  44. cout << fullName << endl;
  45. delete [] fullName;
  46. }

Now of course I'm getting errors because I am painfully aware of my lack of skill in passing the arrays...what am I missing?
Last edited by henpecked1; Mar 14th, 2008 at 1:52 pm.
Reply With Quote Quick reply to this message  
Join Date: Dec 2007
Posts: 226
Reputation: henpecked1 is an unknown quantity at this point 
Solved Threads: 1
henpecked1 henpecked1 is offline Offline
Posting Whiz in Training

Re: HEAP Corruption Error

 
0
  #9
Mar 14th, 2008
Okay, the last post is where I started, every way I've tried to pass those arrays in is met with several errors...what is the syntax for passing them in?
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 269
Reputation: sarehu is on a distinguished road 
Solved Threads: 22
sarehu's Avatar
sarehu sarehu is offline Offline
Posting Whiz in Training

Re: HEAP Corruption Error

 
0
  #10
Mar 14th, 2008
Think about the types of the values you are using. Does strlen(getlast) really make sense? strlen expects a value of type char* , and you're giving it getlast .
Last edited by sarehu; Mar 14th, 2008 at 3:48 pm.
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the C++ Forum


Views: 2590 | Replies: 14
Thread Tools Search this Thread



Tag cloud for C++
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC