In an effort to expand my C++ knowledge, I'm writing a little application that generates a random string of lowercase characters, and then returns a pointer that that array. I've got a majority of the app working, it generates the character array fine, but when I try to read the character array outside of the function, I get a bunch of jargon characters.
Here is my code:
Code:
/*
* Create a random string
*/
char* randfname() {
int len = 16; // len of str
srand(time(0)); // to get a true random number
char fname[len]; // char arr that stores file name
char* ptr = fname; // pointer to fname
for(int i = 0; i < len; i++) {
int ascii = (rand() % 25) + 97; // Randomally generate ascii lower case
*(ptr+i) = ascii;
// fname[i] = ascii;
}
for(int i = 0; i < len; i++) { // Test print char arr w/ ptr
cout << *(ptr+i); // Works here
}
return ptr;
}
...
/*
* Test function to ensure that randfname()
* is working.
*/
void testrandfname() {
char* ptr = randfname(); // call randfname
cout << endl;
for(int i = 0; i < 16; i++) {
cout << i << ": " << *(ptr+i) << endl;
}
}
When I print out the array in the randfname() function, it works fine, however, when I pass the pointer to the testrandfname() function and I attempt to print out the array, it doesn't work and I get rubbish data.
I think there is an error where I assign the char* ptr to the pointer returned from randfname() but I'm not sure.
I've tried several different things, but I always arrive at printing rubbish data. Could anybody help me properly read the character array that is returned?
The problem is that ptr points to the first element of the local array named fname. When control returns from this function, the array is destroyed, so the caller gets a pointer to an element that no longer exists.
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar
Oh, incidentally, you were using a compiler extension earlier: fname is actually a variable length array. If you really intend a fixed size array, you could consider a std::tr1::array<int, 16>, but a TR1 implementation may not be available for you to use.
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar
Actually, if I passed a pointer to the array (which is set by the calling function) to randfname, and the length of the array, the array would be preserved right? And I could use that array in the calling function right?
Actually, if I passed a pointer to the array (which is set by the calling function) to randfname, and the length of the array, the array would be preserved right? And I could use that array in the calling function right?
Yes.
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar
For completeness: Another "solution" would be to declare fname as static, thus it would continue to exist after the function exited.
Solution is written in quotes, as this approach imposes a complete new set of problems, i.e. dependencies between multiple calls to this function and the unability to use this function in multi-threaded program. Therefore the "For completeness".
More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf
Premature optimization is the root of all evil --Donald E. Knuth
Bookmarks