![]() |
|
#1
|
|||
|
|||
return string from a functionHello... I found that I could return a string literal form a function using the functions char* return variable only without passing a string address to the function... I was suprised because I thought it would pass out of scope as the function ended.... but it works for a printf (below).
So I thought this might work for a 'char string[x]' as well.... but I haven't been able to get anything to work. I stare at it and wonder WHY? What have I done to displease you ??????..... Your brother "1234" behaves... Why can't YOU? really..What would be the difference between "1234" and those same chars in an array? How can I get that array to look like the string literal ??? Below I have tried three different methods in three functions. One and three work. Functoin two is what I've been banging my head on: CPP / C++ / C Code:
Code:
Well, my intended functions purpose would be to generate a digit string for %s output to a printf as shown. It will already have three arguments passed to it, so it would be nice not to have to have a fourth. Thanks, Howard; |
|
#2
|
||||
|
||||
Re: return string from a functionQuote:
Quote:
An array is destroyed (or at least available to be reused immediately) when the function returns. Therefore -- stop beating your head against a wall. If you make the array static, you will have no problem... statics are persistent. __________________
Age is unimportant -- except in cheese |
|
#3
|
|||
|
|||
Re: return string from a functionQuote:
I had not though of trying a static, and while I knew a static must be somewhere in memory for a function to be able to pick up values where it left off on it's last call, but I didn't realize that there could be other uses for that characteristic such as a pointer to that space could be picked up and used in another function. CPP / C++ / C Code:
Code:
Besides printf being able to print the string, I can even use the pointer elsewhere in the program as illustrated by the use in assignment to 'char *cptr' in main() and the printf(). Neat stuff, thanks again! ++Howard; Last edited by Howard_L : 17-Aug-2007 at 13:14.
|
|
#4
|
|||||
|
|||||
Re: return string from a functionQuote:
It could be considered dangerous to pass a pointer to a string literal unless you use the "const" qualifier, so a better programming practice might be something like the following: CPP / C++ / C Code:
You are telling the compiler that the function is returning a pointer to an array whose contents will not change. Then try the following in your main(): CPP / C++ / C Code:
You should get compiler warnings about the assignment statement for cptr = func1(). These are warnings, and in fact by declaring things the way that you did, the result of cptr[1] = 'X' is undefined behavior. Since they are only "warnings", an executable is generated, and you can run it. Current versions of GNU compilers actually have a separate read-only data space, and if I run the program, I get a "STATUS_ACCESS_VIOLATION" error and stackdump. Borland and Microsoft compilers that I have will cheerfully allow you to )illegally) change the contents of memory where the string literal resides. As I have mentioned about a million times (maybe more), undefined behavior is undefined. It is not guaranteed to cause an error, but it might cause an error (or it might, under some circumstances, lead to apparently correct results). By declaring a pointer to a const array, at least the compiler can be helpful enough to give a warning in case I have a mental lapse (or if other programmers want to use my beautiful function) and try to change something that I had previously promised not to. With your original definitions (no const), none of the compilers gave a warning. The results were, of course, the same: ACCESS_VIOLATION runtime error with gcc, benign behavior with the others. Bottom line: If you are going to return a pointer to some read-only memory (like a string literal), it is safer to use "const" in the declaration/definition. (And, don't (don't) ignore the compiler warnings.) Quote:
Not a chance. Well let me be a little more precise and say that this is unconditionally, absolutely undefined behavior. You are setting the value of a pointer to an address of local automatic storage (usually said to be "on the stack"). You return the value of the pointer. But the memory that this is pointing can no longer be legally accessed. Period. Full stop. Quote:
CPP / C++ / C Code:
The value of cp1 is the address in program data memory of some "stuff". You pass the value of that address back to the calling function. In func2() CPP / C++ / C Code:
You set a pointer value to be the address of the first element of the array. So far, so good. Now, you pass the value of that address back to the calling function. The memory that was assigned to the local array txt[] is no longer legally accessible. Quote:
If you want to initialize an array with a string literal, you could do something like CPP / C++ / C Code:
or, let the compiler count for you, and just simply say CPP / C++ / C Code:
and the result would be exactly the same as it was with your statement: CPP / C++ / C Code:
Yes, exactly. In either case, the array will go out of scope at the end of the function/block where the array is declared, so you can't legally access it after returning to the calling function. Now, there is a way to make the array not only available, but read-writeable outside its function. Actually there are two ways. Neither is recommended as a general programming practice, for various structured programming reasons. 1. Declare the array outside the function in such a way that it is visible to other functions in the file. Declaring it before main(), would give it file scope (sometimes called a "global" variable, since it is available to all functions in the program). By declaring it globally and not inside any function, you wouldn't have to pass pointers to it to or from functions. I hate to repeat myself, but this is generally not recommended as a general-purpose Good Thing to Do. That's not to say that one should never use global variables, but getting into the habit of using globals just for the heck of it (or just to avoid having to pass a pointer as a function argument) may very well lead to grief some day. My friendly advice: Don't show up for a design review or a peer code review with a lot of global variables unless you are ready to defend their use. (Free advice, freely given, and it is, after all, only an opinion.) 2. Declare the array to be static inside the function. The array will reside somewhere in program data space (not the stack), and the contents of the array will be unchanged from one function call to the next, and if you pass a pointer to that memory back to the calling function, it will be valid for access on other places in the program. Note that if you initialize the array in the declaration statement inside the function, the memory is initialized at load time and not re-initialized when you call the function. As in the case of global variables, static variables in functions may present some difficulties. In addition to making debugging more problematic, they really play havoc with programs written with threads (--don't get me started---see footnote), and they make the functions non-reentrant. If you don't know or don't care about such things, then don't worry about it now. But some day you may care. Or, maybe, not. My friendly advice: In general, if you don't need to change the contents of the array outside of the function, just use a string literal and return a pointer as you did in your first example. If you do need to change the contents, inside or outside the function, then pass a pointer into the function as an argument. Your func3 works because you "did it right". However, I have one final comment. You should realize that the number in the brackets, [8], is irrelevant. The function will always get a pointer to char. Yes, always. You could declare/define func3 the way that you did, but I would rather see either CPP / C++ / C Code:
CPP / C++ / C Code:
All three ways (your way and my two examples) are exactly the same to the compiler. The reason that I don't like your way (especially on a forum that is visited by less-experienced programmers trying to figure out what the heck we are talking about) is that sometimes people tend to think that defining it the way that you did tells the function that it the parameter is an array of eight chars. It's really important to know that this is simply not true. There is no way (no way) that a function can know the size of an array in its argument list unless you tell it (probably with another parameter). The array gets a pointer to char. (But I already said that.) Quote:
Well, I don't believe that using global variables or static variables as a general program practice is justified by someone's perception of "niceness". If your function is going to operate on an array, I say pass it a pointer to the array. Of course that's just an opinion, and as always, Your Mileage May Vary. Regards, Dave Footnote: "A computer is a state machine. Threads are for people who can't program state machines." ---Linux kernel guru, and fine human being, Alan Cox |
|
#5
|
|||
|
|||
Re: return string from a functionI thought this might have been a redundant thread to start but has turned out to be very concise. Excellent replies you guys. I understand MUCH more now! And it's making sense!
Even though static works well, I think I'll just be going for the fourth argument in the call in a continuing effort to learn good programming practices. Learn to practice, practice to learn... Speaking of which I'll be getting back to finishing up that function which goes into the darn project (which also had the #ifdef etc.) I started days ago. I keep running into these interesting forks in the road....a day here , a day there and another week goes by.... Thanks Again, ++Howard; |
Recent GIDBlog
Developing GUIs with wxPython (Part 3) by crystalattice
| Thread Tools | Search this Thread |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| need help with a console menu system | BullBuchanan | C++ Forum | 6 | 20-Aug-2006 14:46 |
| Reading non ASCII with read() | Atomical | C Programming Language | 8 | 13-Sep-2005 14:30 |
| Help wit my source code compiler errors | Krandygrl00 | C++ Forum | 1 | 06-Jun-2005 08:14 |
| Problem with one variable | bretter | C++ Forum | 1 | 16-May-2005 07:20 |
| C++ file I/O | CronoX | C++ Forum | 36 | 09-Mar-2004 17:28 |
Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The