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

void punchmeinthehead()
{
	const int maxin = 16;
	char lastName[maxin] ;
	char firstName[maxin] ; 
	char midName[maxin] ;
	
	size_t length = strlen(lastName) + strlen(firstName) + strlen(midName) + 1;
	char  *fullName = new char[length];
	strcpy (fullName, lastName);
	strcat (fullName, " ");
	strcat (fullName, firstName);
	strcat (fullName, " ");
	strcat (fullName, midName);
	cout << fullName << endl;
	delete [] fullName;
}

Main looks like this

void main()
{
	const int maxin = 16;
	char lastName[maxin];
	char firstName[maxin]; 
	char midName[maxin];

    	
	getlast(lastName, maxin);
    getfirst(firstName, maxin);
    getmid(midName, maxin);
	punchmeinthehead();
	
}

The calling functions look like this

void getlast( char lastName[] , int maxin)
{
	cout << " Please enter your last name up to 15 characters " << endl;
	cin.getline(lastName, maxin, '\n' );
	cin.ignore (cin.rdbuf()->in_avail(), '\n');
	
}


//Input first name
void getfirst( char firstName[] , int maxin)
{
	cout << " Please enter your first name up to 15 characters " << endl;
	cin.getline(firstName, maxin, '\n' );
	cin.ignore (cin.rdbuf()->in_avail(), '\n');
	
}


//Input middle name
void getmid( char midName[] , int maxin)
{
	cout << " Please enter your middle name up to 15 characters " << endl;
	cin.getline(midName, maxin, '\n' );
	cin.ignore (cin.rdbuf()->in_avail(), '\n');
}

Recommended Answers

All 14 Replies

void punchmeinthehead()
{
	const int maxin = 16;
	char lastName[maxin] ;
	char firstName[maxin] ; 
	char midName[maxin] ;
	
	size_t length = strlen(lastName) + strlen(firstName) + strlen(midName) + 1;
	char  *fullName = new char[length];
	strcpy (fullName, lastName);
	strcat (fullName, " ");
	strcat (fullName, firstName);
	strcat (fullName, " ");
	strcat (fullName, midName);
	cout << fullName << endl;
	delete [] fullName;
}

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.

About the punchmeinthehead() function ...

void punchmeinthehead()
{
	const int maxin = 16;
        // Here you have three uninitialized arrays of char, use a 
        // debugger to see what they contain here ...
        // (Shouldn't you instead be using the variables 
        //  that you have in your main() ?)
	char lastName[maxin] ;
	char firstName[maxin] ; 
	char midName[maxin] ;
	
        // if your three arrays are OK at this point, the following works
	size_t length = strlen(lastName) + strlen(firstName) + strlen(midName) + 1;

	char  *fullName = new char[length];
        // fullname may also be NULL at this point
	<snip>
        // Did you account for the extra space character when 
        //  allocating memory?
	strcat (fullName, " ");
	<snip>
}

Hmm .. you could rename punchmeinthehead() to punchmeintheheap() ...

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?

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

void punchmeinthehead()
{
	const int maxin = 16;
	char lastName[maxin] ;
	char firstName[maxin] ; 
	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.)

void punchmeinthehead()
{
	const int maxin = 16;
	char lastBlah[maxin] ;
	char firstBlah[maxin] ; 
	char midBlah[maxin] ;
	
	size_t length = strlen(lastBlah) + strlen(firstBlah) + strlen(midBlah) + 1;
	char  *fullName = new char[length];
	strcpy (fullName, lastBlah);
	strcat (fullName, " ");
	strcat (fullName, firstBlah);
	strcat (fullName, " ");
	strcat (fullName, midBlah);
	cout << fullName << endl;
	delete [] fullName;
}

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.

size_t length = strlen(lastName) + strlen(firstName) + strlen(midName) + 1;
	char  *fullName = new char[length];
	strcpy (fullName, lastName);
	strcat (fullName, " ");
	strcat (fullName, firstName);
	strcat (fullName, " ");
	strcat (fullName, midName);
	cout << fullName << endl;
	delete [] fullName;
}

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 :

void getlast( char lastName[] , int maxin)
{
	cout << " Please enter your last name up to 15 characters " << endl;
	cin.getline(lastName, maxin, '\n' );
	cin.ignore (cin.rdbuf()->in_avail(), '\n');
	
}

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:

void getlast( char something[] , int maxin)
{
	cout << " Please enter your last name up to 15 characters " << endl;
	cin.getline(something, maxin, '\n' );
	cin.ignore (cin.rdbuf()->in_avail(), '\n');
	
}

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.

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.

commented: Sarehu was very helpful in explaining my own stupidity without calling me stupid +1

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

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:

#include "nameinp.h"
#include <iostream>
#include <string.h>
using namespace std;

//Input last name
void getlast( char lastName[] , int maxin)
{
	cout << " Please enter your last name up to 15 characters " << endl;
	cin.getline(lastName, maxin, '\n' );
	cin.ignore (cin.rdbuf()->in_avail(), '\n');
	
}


//Input first name
void getfirst( char firstName[] , int maxin)
{
	cout << " Please enter your first name up to 15 characters " << endl;
	cin.getline(firstName, maxin, '\n' );
	cin.ignore (cin.rdbuf()->in_avail(), '\n');
	
}


//Input middle name
void getmid( char midName[] , int maxin)
{
	cout << " Please enter your middle name up to 15 characters " << endl;
	cin.getline(midName, maxin, '\n' );
	cin.ignore (cin.rdbuf()->in_avail(), '\n');
}

void punchmeinthehead()
{

	size_t length = strlen(getlast) + strlen(getfirst) + strlen(getmid) + 3;
	char  *fullName = new char[length];
	strcpy (fullName, getlast);
	strcat (fullName, " ");
	strcat (fullName, getfirst);
	strcat (fullName, " ");
	strcat (fullName, getmid);
	cout << fullName << endl;
	delete [] fullName;
}

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?

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?

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 .

I understand that it's expecting some form of input coming from my array, and that I have to give it the contents of that array. I just didn't know how. This is what I've tried so far:

strlen (lastName) //errors 
strlen (getlast (lastName,maxin) //errors
strlen (lastName[]) //errors
strlen(*lastName) //errors
strlen(*lastName[]) //errors

I'm assuming from the * that you're saying to use a pointer, but thats where I'm running into trouble, is how to write that, I'm at a loss. After your post I tried this:

strlen (char* lastName[])

and that gives me errors too. I appreciate your patience, but I'm obviously clueless

Or, maybe now that I think about it a little bit and seeing a couple of examples, maybe one of my original tries was syntactically correct, but missing a declaration?

char* lastName = lastName[];
strlen (lastName)  ;

my pointer declaration might be backwards, but is that what I'm missing? A pointer declaration? My battery in the laptop is dead or I'd just try it out and see, but I can't as I don't have a compiler on this machine

hint:

char* punchmeinthehead( const char* first_name, 
                        const char* middle_name, 
                        const char* last_name )
{
   // ...
   // delete[] fullname ; // instead
   return fullname ;
}

That was my next thought, but I wasn't sure if I could pass all three at once, I'll try it when I get home.....than you V

Many thinks to Vijayan and Sarehu for their help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.