Segmentation Fault after declaring char* inside function

Feb 15, 2022 at 8:19pm
Hello. I was trying to make a name generator for my game project, but to no success. I have defined a global char* names[], as well as some other C-style string arrays to store things like locations, races and titles. My objective is to call the function, which will randomly generate a name following the [name]->[", the "]->[adjective]->[" "]->[race]->[" from "]->[location] format. But that's not the issue, I managed to work that part out, the problem is the program gives me a Segfault error when I run it, and as far as I have tested, it happens as soon as I declare the variable that will serve as the return value. What could I possibly be doing wrong? All tips are appreciated.
Follows the function:

1
2
3
4
5
6
7
8
9
10
11
12
13
char* generateName()
{
	char* strRet = {'\0'};
	printf("DEBUG: DECLARED STRRET. ITS VALUE IS: \"%s\"", strRet);
	strcat(strRet, name[randomInt() % (sizeof(name) / sizeof(name[0]))]);
	strcat(strRet, " the ");
	strcat(strRet, adjective[randomInt() % (sizeof(adjective) / sizeof(adjective[0]))]);
	strcat(strRet, " ");
	strcat(strRet, race[randomInt() % (sizeof(race) / sizeof(race[0]))]);
	strcat(strRet, " from ");
	strcat(strRet, location[randomInt() % (sizeof(location) / sizeof(location[0]))]);
	return strRet;
}


PS. You might be wondering why I'm not using std::strings instead of C-style strings. Answer is I'm using Ncurses, so it makes it everything easier. Of course I could make a workaround to make it all work, but I just prefer it the way it is.
Feb 15, 2022 at 8:35pm
You may want to declare strRet as an array instead of a single character. And remember that the first argument of strcat must have an array size that is large enough to hold the combined C-string.

What exactly are you trying to do with that second parameter?

Do you realize you are trying to return a local C-string from that function and that is not allowed.

If I were you I would stick with std::string for most operations. If you need to send a C-string to one of the "curses" functions then just use the std::string.c_str() function to convert the std::string to a C-string.

Also why all the global variables? You really need to learn how to use parameters to pass values to and from your functions.

Feb 15, 2022 at 8:39pm
Yep, that sounds about right, I guess I'll use std::string then, and thanks for the tips.
The second parameter is selecting a random index from the respective C-style strings array.
Last edited on Feb 15, 2022 at 8:42pm
Feb 15, 2022 at 8:40pm
The problem is called "dangling pointer". When generateName returns strRet goes out of scope and gets destroyed. Still the pointer in the receiving functions points to it.

Consider using std::string. If necessary you can pass a char* to ncurses with data() or c_str().

Another option is to allocate strRet on the heap with malloc and return it. However the receiving function has to remember to free it.
Feb 15, 2022 at 8:57pm
The second parameter is selecting a random index from the respective C-style strings array.

Also remember that the both parameters of strcat() must be C-strings, not just an array of char. A C-string is an array of char that is terminated by the end of string character '\0'.



Topic archived. No new replies allowed.