C-strings vs. String Objects Flashcards
What is a c-string?
An array of characters terminated by the null character: \0
What is a c-string that is NOT terminated by the null character?
A character array. All c-strings are null-terminated, otherwise it’s not a c-string.
How is a string literal in code implemented?
For example: “Hello World” or “John Smith”
String literals are implemented as constant c-strings.
What are the 4 main downsides of C-strings?
- Fixed length – not very flexible.
- Since it’s an array, it always has to be passed to functions by address.
- No inherent boundary checking, even with library functions, so overflow is a constant consideration.
- Not very intuitive to use. Requires understanding its limitations and workarounds.
I want to assign “Hello World” to a string called greeting:
char greeting[40];
// Will this work?
greeting = “Hello World”;
No.
c-strings have to populated by a for loop or the strcpy(); function (which is a for loop), e.g.:
strcpy(greeting, “Hello World”);
// Will this work to compare two c-strings?
if (str1 == str2)
{
// some code
}
Yes, but not the way you would expect.
This will compare two strings to see if they have the same POINTER.
If you want to compare the actual string contents, you need to use a function like strcmp():
// This returns true if the strings have the same contents
if (strcmp(str1, str2) == 0)
If you wanted to have a c-string with a variable size, how would you accomplish it?
The c-string’s size would have to be dynamically allocated and then adjusted to the needs of the string’s changing length.
// What prints here?
char vowels[5] = {‘A’, ‘E’, ‘I’, ‘O’, ‘U’};
std::cout «_space;vowels;
std::cout treats character arrays as though they are c-strings, and expects them to be null-terminated. However, vowels is a character array with no null-termination (meaning it is not a c-string.
The effect is that std::cout will print AEIOU, and then it will KEEP GOING past the array boundary and print everything in contiguous memory until it hits a null character or results in a segmentation fault.
// What would happen here?
char greeting[25] = “Take me to your leader”; // length 22, capacity 24
char welcome[10] = “Hello”; // length 5, capacity 9
strcpy(welcome, greeting);
Since greeting[25] is larger than the capacity of the target string, welcome[10], strcpy will write the excess characters of greeting into the memory outside the borders of welcome’s array.
At best, this will lead to the corruption of the data that was already occupying the memory immediately beyond the array in the stack. At worst, it will result in a segmentation fault.
// Examine this and explain the answer to the question at the end comment
char buffer[40] = “Dog”; // length 3, capacity 39
char word2[] = “food”; // length 4, capacity 4
strcat(buffer, word2); // buffer is now “Dogfood”
strcat(buffer, “ breath”); // buffer is now “Dogfood breath”
strcat(buffer, buffer); // plenty of room for this, right?
No.*
strcpy() will start modifying the original c-string, but that’s also the same c-string being used as a reference to copy from. This causes undefined behavior when the function can no longer properly reference the original contents.
- Some compilers have updated cstring libraries which correct for this error, but compilers that don’t will still have problems. Since an inconsistency exists, it’s safer not to do this from a portability standpoint.