Re: is there any problem if I set a char to '\0' within a string?
from the example you gave (http://www.parashift.com/c++-faq-lit...html#faq-17.11)
I don't understand why he tried to write all that code with simple char* strings.
I would have done like this:
Code:
void userCode(char const* s1, char const* s2)
{
//concatenates strings s1 and s2 and stores it in copy (which means the function does nothing fruitful
int len = strlen(s1) + strlen(s2) + 1;
char* copy = new char[len];
StringCchCopyA(copy, len, s1);
StringCchCatA(copy, len, s2);
delete[] copy;
}
and by the way, null-terminated strings (like char* copy) are faster than string and wstring. And you have all functions you need for working with them. unlike "string": or tell me how you format a string using "string".
Also, if you work with windows API (I do), you inevitably use null-terminated strings (char*, wchar_t*), and, rather than copying them into a "string", etc. and perform operations, it is usually better (and always faster) to work with pure char* and wchar_t* functions.
Re: is there any problem if I set a char to '\0' within a string?
Quote:
I don't understand why he tried to write all that code with simple char* strings.
The try block was to avoid memory leaks. This is right there in the comment.
Quote:
Originally Posted by Feoggou
I would have done like this:
Please note that this is the Non Visual C++ Issues forum. Furthermore, your example is flawed as a comparison: there is only one use of new[], so there is no worry about a memory leak should an exception be thrown. This is different from the example that you are criticising.
Quote:
Originally Posted by Feoggou
and by the way, null-terminated strings (like char* copy) are faster than string and wstring.
It depends.
Quote:
Originally Posted by Feoggou
And you have all functions you need for working with them. unlike "string": or tell me how you format a string using "string".
You could use a stringstream, Boost.Format if it is available, or if you prefer, make use of null terminated string formatting functionality through the c_str() member function.
Re: is there any problem if I set a char to '\0' within a string?
Quote:
The try block was to avoid memory leaks. This is right there in the comment.
sorry for asking, but how can a memory leak happen there?
Quote:
Please note that this is the Non Visual C++ Issues forum. Furthermore, your example is flawed as a comparison: there is only one use of new[], so there is no worry about a memory leak should an exception be thrown. This is different from the example that you are criticising.
I don't get it: why is it wrong that I use only a new? if I know exactly how much I need, it is pointless to use 2 strings and 2 new[] operations.
by the way, doesn't C++ have strcat? why worry so much with strcpy when you need to concatenate strings?
and I understand that simple C++ doesn't have "strcat_s", right?
Re: is there any problem if I set a char to '\0' within a string?
Quote:
Originally Posted by Feoggou
sorry for asking, but how can a memory leak happen there?
Let's remove the try/catch blocks from that example:
Code:
void userCode(char const* s1, char const* s2)
{
char* copy = new char[strlen(s1) + 1]; // make a copy
strcpy(copy, s1); // of s1...
...code that fiddles with copy...
char* copy2 = new char[strlen(copy) + strlen(s2) + 1]; // append s2
strcpy(copy2, copy); // onto the
strcpy(copy2 + strlen(copy), s2); // end of
delete[] copy; // copy...
copy = copy2;
...code that fiddles with copy again...
delete[] copy;
}
Now, suppose an exception is thrown on this line:
Code:
char* copy2 = new char[strlen(copy) + strlen(s2) + 1]; // append s2
Control leaves the body of the function such that it reaches an appropriate handler for the exception. Unfortunately, this means that this line will never get executed, thus resulting in a memory leak:
Quote:
Originally Posted by Feoggou
I don't get it: why is it wrong that I use only a new? if I know exactly how much I need, it is pointless to use 2 strings and 2 new[] operations.
The flaw is in the comparison: you are comparing a case where the try/catch blocks are unnecessary to a case where they are necessary.
Quote:
Originally Posted by Feoggou
by the way, doesn't C++ have strcat? why worry so much with strcpy when you need to concatenate strings?
You might want to read this article entitled Back to Basics by Joel Spolsky. As an example, it explains why you should be wary of the repeated use of strcat. That said, in this case it was rather pointless to avoid strcat, since strlen(copy) results in the same unnecessary computation, unless an optimising compiler recognises that the result will be the same. But if that string length had been cached (like how it is for std::string), then using strcpy as demonstrated would have been more efficient.
Quote:
Originally Posted by Feoggou
and I understand that simple C++ doesn't have "strcat_s", right?
strcat_s is not part of the C++ standard library.
Re: is there any problem if I set a char to '\0' within a string?
Quote:
Originally Posted by
Feoggou
I don't get it: why is it wrong that I use only a new? if I know exactly how much I need, it is pointless to use 2 strings and 2 new[] operations.
Let's say for some reason you need 2 new[] operations, though. If the second one throws an exception, then the first will become a memory leak if you don't have a try/catch. With only one new[] this is less of an issue. Still, the very possibility is reason enough to prefer RAII containers such as std::string or std::vector rather than using new[] directly.
Quote:
by the way, doesn't C++ have strcat? why worry so much with strcpy when you need to concatenate strings?
A strcat() call is effectively equivalent to a strlen() on the first string followed by a strcpy() from the second to the first. This makes it linear in the combined length of the two strings (or amortized linear if you consider the possibility of reallocations and assume a smart reallocation scheme such as doubling capacity as necessary).
By contrast, std::string::operator+= is also linear (or amortized linear if there's a reallocation)----but if no reallocation is necessary, then it's linear in the size of the second string rather than in the size of both together. So it's probably slightly faster. And in addition, and necessary reallocation details are handled transparently, so it's a lot harder to screw it up via bad code or a poor choice of reallocation scheme.
Quote:
and I understand that simple C++ doesn't have "strcat_s", right?
Correct, that's one of the Microsoft extensions to the C standard library which serves little purpose except to reduce portability. Maybe if you're stuck in pure C land they could be some small aid to safety, but doing things the C++ way is usually a better option.
Re: is there any problem if I set a char to '\0' within a string?
Quote:
Now, suppose an exception is thrown on this line:
Code:
char* copy2 = new char[strlen(copy) + strlen(s2) + 1]; // append s2
ok, but let's suppose an exception is thrown here:
Code:
char* copy = new char[strlen(s1) + 1];
isn't this possible? If it is, this is unhandled.
Re: is there any problem if I set a char to '\0' within a string?
Quote:
Originally Posted by
Feoggou
ok, but let's suppose an exception is thrown here:
Code:
char* copy = new char[strlen(s1) + 1];
isn't this possible? If it is, this is unhandled.
That would be fine. There is nothing to delete[] at that point (or more generally, no resources to deallocate), at least not within the scope of the function.
Re: is there any problem if I set a char to '\0' within a string?
so you mean that if there was a code like this:
Code:
char* buffer1 = new char[24];
char* buffer2 = new char[35];
....
delete[] buffer2;
delete[] buffer1;
there would be no problem with the first, but with the second there could be?
if yes, why is it so?
Re: is there any problem if I set a char to '\0' within a string?
Quote:
Originally Posted by Feoggou
there would be no problem with the first, but with the second there could be?
More like: the second could cause a problem for the first.
Quote:
Originally Posted by Feoggou
if yes, why is it so?
I have already explained it to you, and Lindley confirmed it: an exception could be thrown (in particular, std::bad_alloc, though if you were dealing with class types, other exceptions may also be possible), causing control to leave the scope such that the delete[] for the already allocated dynamic array of objects is never executed. In short, the code is not exception safe.
Re: is there any problem if I set a char to '\0' within a string?
I asked that question because... when I learnt C++ years ago (I don't think STL was then, at least I did not have access a book with STL) I did not meet examples like this:
Code:
try {
p = new int (87);
} catch (bad_alloc xa) {
cout << "Allocation Failure\n";
}
so my question was, what could go wrong? not sufficient memory available? what else is possible?
Re: is there any problem if I set a char to '\0' within a string?
Quote:
Originally Posted by Feoggou
so my question was, what could go wrong? not sufficient memory available? what else is possible?
Insufficient memory, or perhaps insufficient contiguous memory for the desired allocation, is one potential problem. If you are constructing objects of some class type, the constructor might throw an exception, e.g., due to invalid arguments or some other constraint violation.
The solution that I recommended in my first reply in this thread is basically RAII: associate the lifetime of a resource, such as memory, with that of an object whose destructor will free the resource when the object is destroyed, usually because the variable goes out of scope.
Re: is there any problem if I set a char to '\0' within a string?
ok, thanks for all your help.