character arrays and strings

Moderator
Posts: 365
Joined: 2002.04
Post: #16
akb825 Wrote:As for casting the result, the only person you need to worry about screwing up is yourself. If you don't do anything with it that will cause troubles, and there is no other way to put that string into the variable (as in this case), I see no problem with it.
The whole point of const is to protect you from yourself. Unless you never make mistakes, you benefit from getting this right by not having to spend hours debugging stack trashing errors and the like. If you get it right everywhere, you never need to do a const cast in any case (because you should never need to const pointers to functions that want non-const ones).

Another benefit of using const is that the compiler can make certain optimisations that would otherwise be impossible.

The only time you should allow yourself to cast away const is when dealing with brain dead library APIs that can't be modified.

Neil Carter
Nether - Mac games and comic art
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #17
I usually try to leave consts alone, but when I'm not going to be modifying the data anyway and need to assign it to a non-const variable for some odd reason, I don't worry about it that much. Such situations are rare, though, so it's almost always a non-issue.
Quote this message in a reply
Atomical
Unregistered
 
Post: #18
My whole program is coded in character strings. I'm not about to switch that around.
Quote this message in a reply
Oldtimer
Posts: 834
Joined: 2002.09
Post: #19
There is also a performance benefit to be had from using const correctness. The compiler can make assumptions and replace expressions, avoid copies, and all sorts of good things. <3 const correctness.
Quote this message in a reply
Atomical
Unregistered
 
Post: #20
NCarter Wrote:You shouldn't cast the result of .c_str() (or virtually anything else) to remove constness. It's const so that you don't accidentally trash the private string data.

Moreover, you're making a deadly mistake here. 'url_string foo' is local. You just took a pointer to an internal buffer in one of its members. When the function returns, foo is destroyed and the buffer no longer exists. Attempting to access the returned pointer may return garbage, and writing to the pointer will probably trash the stack.

Seriously, use std::string. If you really don't want to, just use standard C string functions everywhere so that you can get your constness right.

How do I passe the const back to the arguments?
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #21
You mean assign a const to a parameter? The only way is to cast away the const.

But like I said earlier: I didn't realize that c_str() merely returned the buffer instead of creating a new string, so you do in fact need to use strdup(), which returns a non-const string. (remember to free it when you're done with it, though).
Quote this message in a reply
Moderator
Posts: 365
Joined: 2002.04
Post: #22
Remember that const pointers are not themselves const; instead, they treat the thing they point to as const. Therefore, if you have a parameter typed as 'const char *value', you can still assign a value to it. See this (and the rest of the page) for more information.

You can therefore do this:

Code:
void Function(const char **value)
{
    value = get_a_const_char_pointer_from_somewhere();
}

void Caller()
{
    const char *result = NULL;
    Function(&result);
}
As usual, don't forget that if you're transferring ownership of a malloc()ed buffer, you need to free() it somewhere. Either that, or allocate a local buffer and have the function populate it. Don't pass pointers to local buffers back to the calling function.

Neil Carter
Nether - Mac games and comic art
Quote this message in a reply
Atomical
Unregistered
 
Post: #23
NCarter Wrote:Remember that const pointers are not themselves const; instead, they treat the thing they point to as const. Therefore, if you have a parameter typed as 'const char *value', you can still assign a value to it. See this (and the rest of the page) for more information.

You can therefore do this:

Code:
void Function(const char **value)
{
    value = get_a_const_char_pointer_from_somewhere();
}

void Caller()
{
    const char *result = NULL;
    Function(&result);
}
As usual, don't forget that if you're transferring ownership of a malloc()ed buffer, you need to free() it somewhere. Either that, or allocate a local buffer and have the function populate it. Don't pass pointers to local buffers back to the calling function.

Well that works. It just looks really strange to me with the &.
Quote this message in a reply
Atomical
Unregistered
 
Post: #24
Let's say I make a variable
Quote:char* s = (char *)malloc(2000);

Can I pass that to different functions and have the functions modify that variable without double pointers? I allocated a variable inside a function and when the function returns the contents of the variable is removed from memory. Why does this occur?
Quote this message in a reply
Moderator
Posts: 365
Joined: 2002.04
Post: #25
Atomical Wrote:Can I pass that to different functions and have the functions modify that variable without double pointers?
No. If you want a function to modify its parameters, those parameters must be pointers to the type of the data you want to modify. If you want to modify a pointer, it must be a pointer to a pointer (or a reference to a pointer in C++, if you prefer).

Quote:I allocated a variable inside a function and when the function returns the contents of the variable is removed from memory. Why does this occur?
Local variables (those which weren't malloc()ed or newed) are deleted when program flow exits the block they were declared in (the function, in this case). This is supposed to happen... it ensures that temporary data is automatically cleaned up and saves you from having to manually delete everything little variable you use. Of course, if you malloc() or new something, you must still free() or delete it somewhere.

You could make a static local variable inside the function (just stick 'static' in front of the declaration), in which case the variable will exist for the entire time your app is running, like a global variable. It would then be 'safe' to return it. You might, for example, make a static string buffer, fill it out, then return a (const!) pointer to it. Certain functions in the C standard library do this. However, it's a really bad idea in general, not least because bizarre things can happen if the function gets called by multiple threads or timers.

Incidentally, I recommend using new and delete instead of malloc() and free() in C++. Use the native tools where possible. Wink

Neil Carter
Nether - Mac games and comic art
Quote this message in a reply
Atomical
Unregistered
 
Post: #26
So what your'e saying is if I create a pointer in main, send that to a function, that in turn sends it to another function that mallocs it and gives it a value that it won't return the data correctly?
Quote this message in a reply
Moderator
Posts: 365
Joined: 2002.04
Post: #27
Atomical Wrote:So what your'e saying is if I create a pointer in main, send that to a function, that in turn sends it to another function that mallocs it and gives it a value that it won't return the data correctly?
If it doesn't send a pointer to a pointer, no, it won't work. You'd just leak the malloc()ed memory when the function returns.

Neil Carter
Nether - Mac games and comic art
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Diferences between array and pointer initialized strings in C ferum 16 6,506 Jan 4, 2006 11:38 PM
Last Post: kelvin
  efficient strings? fabien007 4 3,014 Dec 9, 2005 10:59 PM
Last Post: zKing