unable to print char* pointing to 0 - c++

here the comment2 is printed perfectly. where as comment is not printed and the
program ends as soon as it that statement is executed.
Can anybody provide solution?
#include <iostream>
int main()
{
const char * comment = 0;
const char * comment2 = "hello this is not empty";
std::cout << std::endl;
std::cout << comment2 << std::endl;
std::cout << "printing 0 const char *" << std::endl;
std::cout << comment << std::endl;
std::cout << "SUCCESSFUL" << std::endl;
}

Dereferencing a null pointer is undefined behaviour, and this makes comment a null pointer:
const char * comment = 0;
If you want an empty string change to:
const char* comment = "";
Or use std::string:
std::string comment;

Assigning a pointer to 0 means assigning it to NULL. If you want the character 0, change it to string, "0" or for empty string, "".
const char * comment = "";

std::cout << comment << std::endl;
When comment is 0, we call this a segmentation fault, and is a catastrophic crash. What do you intend to happen here?
do you want const char * comment = "0"; to print 0
You can do const char * comment = ""; to represent empty string.
const char * is a pointer. When 0 is assigned to it, it becomes a null pointer because it is now a pointer to null. When you perform cout, the library tries to access the memory at that location, a process called dereferencing a pointer. This causes a crash as explained below.
From Wikipedia
Dereferencing a null pointer in C produces undefined behavior,[5] which could be catastrophic. However, most implementations[citation needed] simply halt execution of the program in question, usually with a segmentation fault.

const char * comment = 0;
is equal to
const char * comment = NULL;
if you want to print character 0, try below code:
const char * comment = "0";
As you tag c++, better use
std::string comment("0");

Related

char * point to element not the address

void reverse(char * str){
char * end = str;
cout << "str" << str << endl;//ABCDE
cout << "end" << end << endl;//ABCDE
char tmp;
if(str){
while(*end){++end; cout << end << endl;}//ABCDE-->BCDE-->CDE-->DE-->E--> NULL
--end;//end=E
cout <<"--end" << end << endl;
while(str<end){// do swap
tmp = *str;//*str = str[0]
*str++ = *end;//*end = last ele in str[]
*end-- = tmp;
}
}
}
My input is
char test[] = "ABCDE";
cout << test << endl; //ABCDE
reverse(test);
cout << test << endl; //EDCBA
I am feeling not good about the pointer, since c++ primer book says char* pointer to the first element of an array, but when I output the pointer end, it is the content of an array not the address.
Also, reverse(test), I mean to give the address of the first element in an array to the pointer, but it turns out give the whole elements to the pointer.
A char* variable is a pointer to a char. A char[] is an array of char. Now, an array of char can be accessed through a pointer, and for char* it is commonly used for string processing (it's used although for other types, but for char it's much more common).
char test[6] = "ABCDE";
char *start = &test[0]; // will point on A
Accessing the array with the pointer can be done with pointer arithmetic:
char *end = start + 5; // equivalent to char *end = &test[5]
Now when you do:
cout << test;
or
cout << start;
It's actually calling an overload of operator<< that takes a const char*. What this operator does is that it print char starting from the pointer passed until it reaches a null char ('\0').
If you want to print the address contained in the pointer and not the string, you have to cast it to void*:
cout << static_cast<void*>(start);
std::cout is overloaded to print strings for char* .
Try:
char *test = "ABCDE";
std::cout << (void *) test << std::endl;

C++ Concatenating const char * with string, only const char * prints

I am trying to cout a const char *
This is how I convert an int to a string and concatenate it with the const char*
char tempTextResult[100];
const char * tempScore = std::to_string(6).c_str();
const char * tempText = "Score: ";
strcpy(tempTextResult, tempText);
strcat(tempTextResult, tempScore);
std::cout << tempTextResult;
The result when printing is: Score:
Does anyone know why the 6 is not printing?
Thanks in advance.
As the docs for c_str say, "The pointer returned may be invalidated by further calls to other member functions that modify the object." This includes the destructor.
const char * tempScore = std::to_string(6).c_str();
This makes tempScore point to a temporary string that no longer exists. You should do this:
std::string tempScore = std::to_string(6);
...
strcat(tempTextResult, tempScore.c_str());
Here, you're calling c_str on a string that continues to exist.
You have marked this post as C++.
One possible C++ approach: (not compiled, not tested)
std::string result; // empty string
{
std::stringstream ss;
ss << "Score: " // tempText literal
<< 6; // tempScore literal
// at this point, the values placed into tempTextResult
// are contained in ss
result = ss.str(); // because ss goes out of scope
}
// ss contents are gone
// ... many more lines of code
// ... now let us use that const char* captured via ss
std::cout << result.c_str() << std::endl;
// ^^^^^^^ - returns const char*

With a string longer than 10 letters, char* changes without any apparent reason. Why?

In step 2 I change only the value of name_C. Why does name_B also change?
Here is the code:
#include <cstdlib>
#include <dirent.h>
#include <iostream>
#include <fstream>
#include <direct.h>
using namespace std;
int main(int argc, char *argv[])
{
// step 1
char *name_A;
char *name_B;
char *name_C;
string str_L = "hello";
string str_M = "stringVar_A"; ;
name_A = (char *) str_M.c_str();
name_B = (char *) (str_L + "-car-" + str_M).c_str();
name_C = (char *) str_L.c_str();
cout << " name_A= " << name_A << endl;
cout << " name_B= " << name_B << endl;
cout << " name_C= " << name_C << endl << endl << endl;
// step 2
string str_N = "myStringMyString"; // (in my real code, i can't put this line in step 1)
string str_R = "ABCDEFGHI" + str_N; // (in my real code, i can't put this line in step 1)
name_C = (char *)str_R.c_str(); // change only name_C
cout << " name_A= " << name_A << endl;
cout << " name_B= " << name_B << endl; // changed, why?
cout << " name_C= " << name_C << endl; // changed, ok.
system("PAUSE");
return EXIT_SUCCESS;
};
Here the output:
(step 1:)
name_A= stringVar_A
name_B= hello-car-stringVar_A
name_C= hello
(step 2:)
name_A= stringVar_A
name_B= ABCDEFGHImyStringMyString
name_C= ABCDEFGHImyStringMyString
With:
string str_N = "myString"; // in step 2...
name_B does not change.
Why does name_B change if str_N is longer than 10 letters?
Can someone help me understand this behavior?
The pointer returned by a call to c_str is only valid for as long as the corresponding std::string stays in scope and is unmodified.
The behaviour in accessing it beyond that is undefined.
For example, (str_L + "-car-" + str_M).c_str(); is returning you the c_str of an anonymous temporary. It will be immediately invalid after the assignment. In your case, name_B is invalidated.
Also, don't cast away the const char* return of c_str(). It's const for a very good reason: you should not attempt to modify the string contents through that pointer.
You are causing undefined behaviour.
name_B = (char *) (str_L + "-car-" + str_M).c_str();
you create a temoprary string from the result of std::string::operator + , extract the C-character array out of it, but then no-one really cathes the temporary string.
when a temporary is not caught by const reference - it is destroyed right away. the string destructor de-allocates the inner character array and invalidates name_B.
so, this is undefined behaviour since you try to work with memory address that is no longer valid.
std::string::c_str() returns a pointer to an internal buffer of a std::string with the guarantee that:
it points to a NUL-terminated string;
the range [c_str(); c_str() + size()] is valid.
In your case, name_B points to an internal buffer of a temporary object name_B = (str_L + "-car-" + str_M).c_str(); which will lead to an Undefined Behaviour when you'll try to use it.
When you make some modifications on your stack (you define two new std::strings), you probably alter the stack place where your name_B points to (since the memory reserved by your temporary has been freed).
If you really have to get old style C-strings from your std::strings, make sure:
The pointer retrieved from std::string::c_str() is no longer used when the std::string is modified or destroyed,
hence you don't call std::string::c_str() from a temporary.

C++ const string literals and custom string class

In C++ string literals "Hello" are const and are immutable. I wanted to make a custom string class whose strings are not const chars, so they can be changeable
Here is a snippet of code that might illustrate what I'm trying to do:
#include <iostream>
class String {
public:
char * p_start;
String(char * strSourc) // Constructor
{
p_start = strSourc;
}
};
int main()
{
String myString("Hello");
// Create object myString, send "Hello" string literal as argument
std::cout << myString.p_start << std::endl;
// Prints "Hello"
*myString.p_start = 'Y';
// Attempt to change value at first byte of myString.p_start
std::cout << myString.p_start << std::endl;
// Prints "Hello" (no change)
myString.p_start = "Yellow";
// Assigning a string literal to p_start pointer
std::cout << myString.p_start << std::endl;
// Prints Yellow, change works. I thought myString "Hello" was const chars, immutable
return 0;
}
So, I'm confused. I've looked everywhere and it says that string literals, like "Hello", are immutable, each of their char bytes are unchangeable. Though I managed to assign Yellow to the p_start pointer, changing the first letter. Though changing the single letter H to a Y through dereferencing the H pointer didn't do anything.
Any insights would help me, thanks.
I think you're confusing about pointer and pointee.
p_start = "Yellow", you're changing the value of pointer, to point to "Yellow". *p_start = 'Y', you're changing the value of pointee, the content p_start points to, not itself. As you said, "Yellow" are const chars, so the behaviour try to modify them is UB.
You can make a copy of it in the ctor, then you can modify the chars, which are managed by the class. Yes, it will be a new copy, but it won't be a waste of memory. And you have no choice if you want them to be changable.
not sure if anyone finds this helpful after so long but since I am learning myself I took your above code and made it work by copying. It now has a member variable for size and cleans up using delete when you assign a new string literal to it (const char*).
#include <iostream>
class String {
public:
char * p_start;
int m_size;
String(const char * strSourc) // Constructor
{
//The following will get the size of the parameter.
int SizeParameter=0;
while (*(strSourc+SizeParameter) != '\0')
{
SizeParameter++;
}
// size of string saved.
m_size = SizeParameter;
// allocate enough memory so we can copy strSourc
p_start = new char[SizeParameter+1];
//copy the contents strSourc
for(int i=0; i<SizeParameter+1; i++)
{
*(p_start+i) = *(strSourc+i);
}
}
//Handle change of string value.
char* AssignNewString (const char* newtext)
{
//clean
delete p_start;
int SizeParameter=0;
while (*(newtext+SizeParameter) != '\0')
{
SizeParameter++;
}
// size of string saved.
m_size = SizeParameter;
// allocate enough memory so we can copy strSourc
p_start = new char[SizeParameter+1];
//copy the contents strSourc
for(int i=0; i<SizeParameter+1; i++)
{
*(p_start+i) = *(newtext+i);
}
return p_start;
}
char* operator=(const char* newtext)
{
AssignNewString(newtext);
}
};
int main()
{
String myString("Hello");
// Create object myString, send "Hello" string literal as argument
std::cout << "string size: " << myString.m_size << std::endl;
std::cout << myString.p_start << std::endl;
// Prints "Hello"
*myString.p_start = 'Y';
// Attempt to change value at first byte of myString.p_start
std::cout << myString.p_start << std::endl;
// Prints "Hello" (no change)
myString = "yellow";
// Assigning a string literal to p_start pointer
myString = "THIS IS A LONGER STRING";
std::cout << myString.p_start << std::endl;
std::cout << "string size: " << myString.m_size << std::endl;
return 0;
}
Note I am learning myself so do let me know if I am doing something wrong. But so far, it seems to work.

What does new [size_t] + 1 return

The following sample of code if from a book "C++ von A bis Z" (second edition, translation: C++ from A to Z) at page 364. The sample is wrong.
// overload operator +=
#include <iostream>
#include <cstring>
using namespace std;
class String {
private:
char* buffer;
unsigned int len;
public:
String(const char* s="") {
// cout << "Constructor: " << s << "\n";
len = strlen(s);
buffer = new char [len+1];
strcpy(buffer, s);
}
~String() {
// cout << "Destructor: " << buffer << "\n";
delete [] buffer;
}
String(const String& s) {
// cout << "Copy_Constructor: " << s.get_buffer() << "\n";
len = s.len;
buffer = new char [len+1];
strcpy(buffer, s.buffer);
}
char* get_buffer() const {
return buffer;
}
// returning a reference is more efficent
// String& operater+=(const String& str1)
String operator+=(const String& str1) {
// cout << "Assignment_Operator +=: " << str1.get_buffer() << "\n";
String tmp(*this);
delete [] buffer;
len = tmp.len + str1.len;
// invalid pointer
// buffer = new char[len+1];
buffer = new char [len]+1;
strcpy(buffer, tmp.buffer);
strcat(buffer, str1.buffer);
// wrong return_type
// return *this;
return buffer;
}
};
int main(void) {
String string1("Adam");
String string2("Eva");
string1+=" und ";
string1.operator+=(string2);
cout << string1.get_buffer() << "\n";
return 0;
}
The lines with the comments are my "fixes". Now I want to know what "new char [len]+1" does? I think the following:
it allocates sizeof(char)*len memory from heap
and returns the WRONG address to the pointer *buffer
but what is the wrong address: "first address of the new memory on heap + 1" or "first address of the new memory on heap + sizeof(char)*1)?
What happens?
Thanks
// edit
Thank you all! You helped me!
I just wanted to know, what this statement will return.
new char [len]+1;
The line itself is, of course, a typo from the author of the book.
Let's break it down:
new char[len];
returns a pointer to an array of char.
new char[len] + 1;
returns the next address in memory.
It's basically cutting off the first character.
EDIT: As others have mentioned, this is most probably a typo, it should be new char[len+1]. I'm just explaining what the code does, but you should only use pointer arithmetics if you really know what you're doing. Trying to delete the returned pointer would be UB, as cHao pointed out. You'll also get UB if len == 1 and attempt to work with the returned pointer.
If you add an integer i to a T*, this will add sizeof(T) * i to the pointer. So in this case, since new char[len] returns a char*, + 1 will indeed add sizeof(char) * 1 to it.
new Type[size] + 1 will allocate an array of size size and yield the address of the element with index 1 - that the second element. Nothing special, just pointer arithmetic. new[] would yield the address of the element with index 0 and size +1 is done on that address it yields address of element with index 1.
It simply returns the pointer to the second array item =)
Read about C pointers ;)
+sizeof(char)*1, but I failed to see why did you do it.
I think it's a typo, and it should be new char [len+1]. The +1 is for the string terminator character that must exist.