It may be hard for you to figure out the cause of the problem assuming that you just finished week 2. The problem deals with concepts like local variables, scope, stack, etc.
You may probably know about local variables and scope and you'll get exposed to the rest as you proceed with the course. I'll try to simplify things as much as I can. If you feel like you still don't get what's in this answer or find it confusing in a way or another, maybe you should give it a look back after you get exposed to concepts above.
What's the cause of the problem?
You're first taking a string from the user via
GetString then you're passing it to
GetInit, you're counting the number of spaces and creating a char array, namely
inits, of size
spaces + 2. Lastly, you're initializing
inits, creating a new string called
initials, then returning that string.
Regardless of the fact that there unneeded steps and there are things that could have been done in a better way,
initials are local variables to
GetInit — as
GetInit returns, these variables go out of scope (i.e., no longer accessible). At this point, trying to access the values of these variables results in undefined behaviors — you never know what you're gonna get.
You probably could conclude now that the rest of the operations that you perform on the value returned by
GetInit have no defined behavior as well and that's why you see the weird stuff printed.
What does this have to do with the printf statements up there?
local variables are stored in an area of memory called the stack.
+ /* stack */ +
Each function that gets called, gets some space reserved for it on the stack. This space is often referred to as the function's stack frame.
The stack frame stores information about the function, its parameters and local variables, the address that the program control is supposed to return to when this function terminates, etc.
main is the first function that gets called in a program, think of the following as a visualization to
main getting a stack frame of it pushed onto the stack.
+ main +
When you call
GetInit, a stack frame of it gets pushed onto the stack as well, in this case, right above
main's stack frame
+ GetInit +
+ main +
As you can probably guess, when you declare
initials (local variables in
GetInit) they get memory allocated for them as part of
GetInit's stack frame on the stack, but here's the interesting thing: When a function ends execution, its stack frame gets popped out of the stack — you may think of it as: the system forgets that there was a stack frame for this function here.
GetInit ends execution, the stack becomes
+ /* left-overs from GetInit's stack frame */ +
+ main +
What's destiny of
GetInit ends execution? We don't really know. The value the used to be in there could still be there or, if for example another function gets called (e.g.,
MakeCap on line 15 and
printf on line 16), it gets a stack frame of it pushed onto the stack and the value that used to live in
initials could get overwritten. That's precisely the reason why trying to access
GetInit terminates has an undefined behavior.
When you call
printf a couple of times atop
main, stack frames get pushed onto and popped from the stack and out of luck the value of
initials (because technically they're the same one value) could survive (i.e., still be there) but of course this doesn't mean that it'll survive forever.
I think the easiest fix would be creating the char arrays that you want to manipulate inside other functions in
main at least if you want still have access to their values after these functions return. Then you pass and modify these char arrays to/in your functions. Example:
void fillWithA(char arr, int size);
#define SIZE 10
printf("%s\n", arr); // outputs AAAAAAAAAA
/* fills arr with 'A's */
void fillWithA(char arr, int size)
for (int i = 0; i < size - 1; i++)
arr[i] = 'A';
// terminate the string
arr[size - 1] = '\0';
In this fix, we're relying on the fact modifying the contents of an array that is passed to a function affects the original array.
main is the last function that gets terminated,
arr in this case doesn't go out of scope until
main returns, so the result of accessing its value after we declare and initialize it is defined.