Trying to reverse a string and getting a bus error - c++

I am trying to reverse a string (but that's not the problem that I have). The problem is trying to change the value of the string array given a certain index. However, every time I try to change the value at the index, I get a bus error. Namely, Bus error: 10. I'm not sure what this means. Also, I tried str[0] = "a" but this also gives me a bus error. Any suggestions to fix this?
#include <iostream>
using namespace std;
void reverse(char* str){
str[0] = 'a';
}
int main(){
char* str = "hello";
reverse(str);
}

Allocate your string as an array on the stack and not as a pointer into a possibly read-only segment of your program.
char str[] = "hello";

First of all, this line should atleast give you a warning:
char* str = "hello";
you are converting a string constant to a pointer, which is not allowed.
To fix your code, you should use, char str[] = "hello" in main().
When you pass this array in reverse(), it decays to char*, now the question which you asked in previous answer's comment.
But when I write cout << str << endl;, why does it print out "hello"? Shouldn't it print only the first character of the string since it points to the first element of the array?
It is because the << operator on std::cout is overloaded. If you give it a char* or const char*, it treats the operand as a pointer to (the first character of) a C-style string, and prints the contents of that string:
const char * str= "hello";
cout << str; // prints "hello"
If you give it a char value, it prints that value as a character:
cout << *str; // prints "h"
cout << str[0]; // prints "h"

Related

Are std::string with null-character possible?

I initialized a C++ string with a string literal and replaced a char with NULL.
When printed with cout << the full string is printed and the NULL char prints as blank.
When printed as c_str the string print stop at the NULL char as expected.
I'm a little confused. Does the action came from cout? or string?
int main(){
std::string a("ab0cd");
a[2] = '\0'; // '\0' is null char
std::cout << a << std::endl; // abcd
std::cout << a.c_str() << std::endl; // ab
}
Test it online.
I'm not sure whether the environment is related, anyway, I work with VSCode in Windows 10
First you can narrow down your program to the following:
#include <iostream>
#include <string>
int main(){
std::string a("ab0cd");
a[2] = '\0'; // replace '0' with '\0' (same result as NULL, just cleaner)
std::cout << a << "->" << a.c_str();
}
This prints
abcd->ab
That's because the length of a std::string is known. So it will print all of it's characters and not stop when encountering the null-character. The null-character '\0' (which is equivalent to the value of NULL [both have a value of 0, with different types]), is not printable, so you see only 4 characters. (But this depends on the terminal you use, some might print a placeholder instead)
A const char* represents (usually) a null-terminated string. So when printing a const char* it's length is not known and characters are printed until a null-character is encountered.
Contrary to what you seem to think, C++ string are not null terminated.
The difference in behavior came from the << operator overloads.
This code:
cout << a.c_str(); // a.c_str() is char*
As explained here, use the << overloads that came with cout, it print a char array C style and stop at the first null char. (the char array should be null terminated).
This code:
cout << a; // a is string
As explained here, use the << overloads that came with string, it print a string object that internally known is length and accept null char.
string end limit (boundary) is not 0 (NULL) like simple char* but its size keep internally in its member data as it's actually user-defined type (an instantiated object) as opposed to primitive type, so
int main(){
string a("abc0d");
a[3] = 0; // '\0' is null char
a.resize(2);
std::cout << a << std::endl; // ab
std::cout << a.c_str() << std::endl; // ab
}
i'm sorry change your code to be more comfortable, watch as it results in
ab
ab
good learning: http://www.cplusplus.com/reference/string/string/find/index.html

Why does printing a char* give a string rather than an address? [duplicate]

This question already has answers here:
Why is address of char data not displayed?
(8 answers)
Closed 6 years ago.
I'm going through the basics of learning C++, but keep hitting a wall when trying to decipher the following about chars and pointers. Included are line comments giving my current understanding of what's going on. Given that I have code like below:
using namespace std;
int main()
{
//String literal is an array of chars
//Array address gets assigned to a ptr of char
char myletters[] = {'h','i'};
char* lp = myletters;
cout << *lp << endl;
//Logically equivalent to above statements
char* letters2 = "hi";
cout << *letters2 << endl;
//String literal turns into array of chars
//Array of chars gets assigned to a ptr of chars
//Each ptr of chars gets stored into letters array
char* letters[] = {"hi","hello"};
cout << *letters << endl;
}
My output will be:
h
h
hi
My question is: when I use the final cout to print the contents of *letters, why do I get the string "hi" rather than the address of "hi" or the address of the first character in "hi"? I get that the first uses of cout are printing a char, and that the last cout is printing a char*, but I'm still wondering why it prints the complete string rather than the address as I would generally expect from a pointer.
Thanks kindly.
the << operator has a special definition for char* that prints the C-string it refers.
In your case, *letters has char* type (being letters a char*[], same as char**) and not char as *lp have.

pointer arithmetic on arrays

When I run the code below my output is not what I expect.
My way of understanding it is that ptr points to the address of the first element of the Str array. I think ptr + 5 should lead to the + 5th element which is f. So the output should only display f and not both fg.
Why is it showing fg? Does it have to do with how cout displays an array?
#include <iostream>
using namespace std;
int main()
{
char *ptr;
char Str[] = "abcdefg";
ptr = Str;
ptr += 5;
cout << ptr;
return 0;
}
Expected output: f
Actual output: fg
When you declare:
char Str[] = "abcdefg"
The string abcdefg is stored implicitly with an extra character \0 which marks the end of the string.
So, when you cout a char* the output will be all the characters stored where the char * points and all the characters stored in consecutive memory locations after the char* until a \0 character is encountered at one of the memory locations! Since, \0 character is after g in your example hence 2 characters are printed.
In case you only want to print the current character, you shall do this ::
cout << *ptr;
Why is it showing fg?
The reason why std::cout << char* prints the string till the end instead of a single char of the string is , because std::cout treats a char * as a pointer to the first character of a C-style string and prints it as such.1
Your array:
char Str[] = "abcdefg";
gets implicitly assigned an '\0'at the end and it is treated as a C-style string.
Does it have to do with how std::cout displays an array?
This has to do with how std::cout handles C-style strings, to test this change the array type to int and see the difference, i.e. it will print a single element.
1. This is because in C there are no string types and strings are manipulated through pointers of type char, indicating the beginning and termination character: '\0', indicating the end.

C++ pointer and array basics

Code:
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
char testChar[] = {'a','b','c'};
char *testPointer = testChar ;
cout << testPointer << endl;
return 0;
}
Question:
When I use cout << mypointer,
Why does to print each letter of the array and the mess(refer to
output) at the end? My assumption is when I see out the pointer
points to the first letter prints then the second then etc and
prints the stuff at the end.
What is the mess (refer to output) at the end , the address?
Comments:
I know at the end of the array there's suppose to be a null pointer right?
I learnt this a year ago and forget please help me recall what is going on.
Output:
abc 310 367 277_ 377
Program ended with exit code: 0
When printing out a string (or char array in your case), it must be terminated by a null character \0, otherwise cout will continue to print out characters located in memory past the intended string until it either hits a null character, or it accesses memory it is not allowed to read from which results in a segmentation fault.
That "mess" at the end that is being printed are the values located in the memory locations immediately past the char array.
Also after initializing char testChar[] = "abc"; you actually don't need 'char *testPointer = testChar' statement since testChar is itself an address to the first element of the array. So cout << testChar << endl;will do.

how to print char array in c++

how can i print a char array such i initialize and then concatenate to another char array? Please see code below
int main () {
char dest[1020];
char source[7]="baby";
cout <<"source: " <<source <<endl;
cout <<"return value: "<<strcat(dest, source) <<endl;
cout << "pointer pass: "<<dest <<endl;
return 0;
}
this is the output
source: baby
return value: v����baby
pointer pass: v����baby
basically i would like to see the output print
source: baby
return value: baby
pointer pass: baby
You haven't initialized dest
char dest[1020] = ""; //should fix it
You were just lucky that it so happened that the 6th (random) value in dest was 0. If it was the 1000th character, your return value would be much longer. If it were greater than 1024 then you'd get undefined behavior.
Strings as char arrays must be delimited with 0. Otherwise there's no telling where they end. You could alternatively say that the string ends at its zeroth character by explicitly setting it to 0;
char dest[1020];
dest[0] = 0;
Or you could initialize your whole array with 0's
char dest[1024] = {};
And since your question is tagged C++ I cannot but note that in C++ we use std::strings which save you from a lot of headache. Operator + can be used to concatenate two std::strings
Don't use char[]. If you write:
std::string dest;
std::string source( "baby" )
// ...
dest += source;
, you'll have no problems. (In fact, your problem is due to the fact
that strcat requires a '\0' terminated string as its first argument,
and you're giving it random data. Which is undefined behavior.)
your dest array isn't initialized. so strcat tries to append source to the end of dest wich is determined by a trailing '\0' character, but it's undefined where an uninitialized array might end... (if it does at all...)
so you end up printing more or less random characters until accidentially a '\0' character occurs...
Try this
#include <iostream>
using namespace std;
int main()
{
char dest[1020];
memset (dest, 0, sizeof(dest));
char source[7] = "baby";
cout << "Source: " << source << endl;
cout << "return value: " << strcat_s(dest, source) << endl;
cout << "pointer pass: " << dest << endl;
getchar();
return 0;
}
Did using VS 2010 Express.
clear memory using memset as soon as you declare dest, it's more secure. Also if you are using VC++, use strcat_s() instead of strcat().