Passing string into functions

Nov 12, 2010 at 10:47pm
Let's say I have the following (full with errors) function:

char* str(char* s)
{
char* s1=s;
char* s2=strcat(s,"Hello");
return s2;
}

i) I believe this function could cause a memory leak since the pointer s2 would be destroyed after returning from the function and its contents will thus become unusable. Am I correct?
ii) Also, does the function argument char *s get a copy of the string? Doesn't the char pointer s also get deleted after returning from the function? Then what happens to the string that s is pointing to? Does it also cause a memory leak? (I doubt it does but I can't explain why not?)
iii)Finally, I believe that the first statement of the function is an incorrect way to copy the string s. It would be (far) better to dynamically allocate memory for s1 and then use strcpy to copy the string. Is this correct?
Nov 12, 2010 at 11:09pm
i) I believe this function could cause a memory leak since the pointer s2 would be destroyed after returning from the function and its contents will thus become unusable. Am I correct?


No. Memory leaks occur when you allocate memory (with new, or since this looks to be C, malloc/calloc) and forget/fail to unallocate it.

strcat does not allocate memory, so the above code does not allocate memory and therefore does not have any memory leaks.

ii) Also, does the function argument char *s get a copy of the string?


No. 's' just points to a buffer. The buffer itself is not copied, only the pointer is.

Basically, you're modifying the exact same string that the calling function has. There is no copy.

strcat appends "Hello" onto whatever string pointed to by s.

So if s points to a buffer containing "Test", after the strcat call, s will contain "TestHello".

Doesn't the char pointer s also get deleted after returning from the function?


No. Nothing here has anything to do with allocation/deallocation. Put that out of your mind.

Then what happens to the string that s is pointing to?


It is being modified by strcat.

iii)Finally, I believe that the first statement of the function is an incorrect way to copy the string s


You are right. That does not copy the string, it simply makes another pointer that points to the same string.

s1 and s2 both == s. All 3 pointers point to the same string. You don't even need s1 or s2 at all here.

It would be (far) better to dynamically allocate memory for s1 and then use strcpy to copy the string. Is this correct?


No, because that would be passing ownership which is sloppy and leads to potential memory leaks.

it would be best to use strings:

1
2
3
4
std::string str(const std::string& s)
{
  return s + "Hello";
}


That way you don't have to worry about these things. But if you are stuck with C and don't have strings, the next best thing, if you don't want 's' to be modified, would be to have a separate buffer passed to the function:
1
2
3
4
5
void str(char* s_out,const char* s_in)
{
  strcpy(s_out,s_in);  // copy the string from 'in' to 'out'
  strcat(s_out,"Hello"); // append "Hello" to it
}
Last edited on Nov 12, 2010 at 11:10pm
Nov 12, 2010 at 11:44pm
Thaks for clearing that up. I would like to clarify some doubts:

i) Let's say in main(), I wrote char* x = str("Hello"); This would lead to unpredictable results since after returning from the function, the space allocated to s2 is returned to the program. Is this correct?

ii) I understand that the code I wrote has nothing to do with memory allocation/deallocation. With that in mind, after returning from the function, is the char* s not destroyed. i.e.its scope is within the function. Surely, s does not "exist" until the end of the program.

iii) Are pointers passed by value since a copy of the pointer is made?
Nov 13, 2010 at 12:03am
i) Let's say in main(), I wrote char* x = str("Hello");


In C++, this shouldn't even compile because "Hello" is a const char* and not a char*. Although, sadly, many popular compilers will allow it.

But yes, it is unpredictable... but not for the reason you think. The real problem is because 'str' would be attempting to modify "Hello", a constant string literal and not a variable buffer.

Remember that str is modifying s:

1
2
3
char buffer[100] = "foo";
str(buffer);
cout << buffer;  // prints "fooHello" 


I understand that the code I wrote has nothing to do with memory allocation/deallocation. With that in mind, after returning from the function, is the char* s not destroyed.


Anything that is automatically allocated is automatically destroyed when its scope ends.

1
2
3
4
{
  int foo;  // foo is automatically allocated here
  foo = 5;
} // foo is automatically destroyed here 


basically: you don't have to worry about it.

Note that there's a difference between the pointer being the destoryed, and the buffer being destroyed. The buffer is what actually holds the string data. The pointer just tells the computer where to find the buffer in memory.

iii) Are pointers passed by value since a copy of the pointer is made?


Technically, yes. But that's kind of a confusing way to look at it.

The buffer is being passed by pointer/reference
The pointer is being passed by value
Nov 13, 2010 at 12:27am
If passing the pointer by value can make a change to the buffer, then what is the use of passing a pointer by reference?

For example, if I pass an integer variable by value, than any changes made to the variable in the invoked function will not reflect a change in the variable outside of that function. I suppose the use of passing a pointer by reference would be the ability to change where it is pointing from the invoked function. Right?
Nov 13, 2010 at 12:47am
If passing the pointer by value can make a change to the buffer, then what is the use of passing a pointer by reference?


Because it would allow you to change the pointer so that it points to something else.

For example, if I pass an integer variable by value, than any changes made to the variable in the invoked function will not reflect a change in the variable outside of that function. I suppose the use of passing a pointer by reference would be the ability to change where it is pointing from the invoked function. Right?


Correct on all points.
Nov 13, 2010 at 12:50am
Thank you very much. You have been very helpful.
Topic archived. No new replies allowed.