views:

90

answers:

2

Hi,
I am trying to learn C++, in the process I tried to write a function that gets two char pointers and concatenate the second one to the first one (I know there is strcat for this).
But - what I want to accomplish is to modify the first parameter pointer so it will point to the result. for this reason I used a reference to pointer in the first parameter.

Before returning from the function I want to free the first parameter memory but I get an error.

Here is the code:

void str_cat(char*& str1, char* str2)
{
 if (!str1)
 {
  str1 = str2;
  return;
 }
 if (!str2)
  return;
 char * new_data = new char[strlen(str1) + strlen(str2) +1];
 char * new_data_index = new_data;
 char * str1_index = str1;
 char * str2_index = str2;

 while(*str1_index)
  *new_data_index++ = *str1_index++;
 while(*str2_index)
  *new_data_index++ = *str2_index++;
 *new_data_index = NULL;

 delete str1; //ERROR HERE (I also tried delete[] str1)

 str1 = new_data;
}

I do not understand why.
Any suggestions?

Thanks,
Itay\

EDIT Here is how I use the function

char * str1 = NULL;
char * str2 = NULL;
str_cat(str1, "abc");
str_cat(str2, "def");
str_cat(str1, str2);
+7  A: 

You can only delete things that were allocated with new - if your code looked like this:

str_cat( "foo", "bar" );

it would be illegal. Basically, your function as it stands is completely unsafe. A better design would be to return the new string via the function's return value. Even better, forget the whole idea and use std::string.

Although learning to use references to pointers is a laudable thing to do, you should be aware that they are used very rarely in C++ programming. You would be much better advised to spend your time learning to use the features of the C++ Standard Library.

anon
I edited the question to show the usage. In any case - my point here was to pass a null pointer and get a value inside it.
Itay
@Itay It still won't work, for a number of reasons. Basically this is a bad design that cannot be safely implemented in C++.
anon
@Neil Butterworth: I got the point of bad design. But still - why it doesn't work?
Itay
+3  A: 

The first call to str_cat() results in str1 being assigned the address of the string literal "abc" that you passed in.
With the third call this becomes a problem as you are trying to delete str1 which, as Neil pointed out, is illegal for string literals.

Georg Fritzsche
Thanks :)Is there anyway to test if it is legal to free a memory location?
Itay
@Itay No, there isn't, which is why the design of the function is bad.
anon
@Itay: No, thats why you shouldn't use such contrived approaches. You could either require that the caller passes in a sufficiently sized buffer or you always return a newly allocated buffer and document how it should be deallocated. Or, as mentioned before, don't do it at all - using `std::string`, `std::vector<char>` et al would get rid of all the problems immediately.
Georg Fritzsche
@Neil Butterworth: Thanks
Itay
@Georg Fritzsche: Thanks
Itay