const char *const changes because of a string (?) - c++

Hello i am building a project and today after 500 lines of code i am going to shoot my self. Today i started a new class and some very strange things are happening:
class Target {
public:
Target(const int port);
virtual ~Target();
private:
const char* initialize_port(const int port) const;
const char *const port;
};
and cpp file:
Target::Target(const int port)
:
port(initialize_port(port))
{
cout<<this->port<<endl; //this cout 80
string test3="Target2";//when i replace with char * test3="Target2" then both couts in the constructor are working ok.
cout<<this->port<<endl; //this cout Target2!!!!!!
}
const char* Target::initialize_port(const int port) const {
string port_str = std::to_string(port);
const char* port_char=port_str.c_str();
return port_char; // OR/and when i replace with something like return "80" then both couts in the constructor are working ok.
}
Target::~Target() {
}
Like you can see in the cpp file, while the default constructor is being called it couts the "this->port", then i create a string, and then i print it again. How is it even possible to get a different response??
From netbeans:
80
Target2
RUN FINISHED; exit value 0; real time: 20ms; user: 0ms; system: 0ms
PS:When in the function initialize_port(const int port) i am giving a standard return, for example return "80"; everything is ok. When in the constructor i am replacing the string with char *, again everything is ok.
PS2:I know that i have some problems with my RAM. If someone will compile and there is no problem with the outputs (cout) please let me know.
Thanks in advance.

The problem comes from:
{
string port_str = std::to_string(port);
const char* port_char=port_str.c_str();
return port_char;
}
When the return happens, port_str is destroyed because it is a locale variable to that code block. Then port_char is a dangling pointer (a pointer that used to point to an object that has now been destroyed).
Using that pointer causes undefined behaviour and that explains your weird effects when you use the pointer.
To fix this, stop using raw pointers. The simplest fix is to use std::string instead.

The problem is that the return value of port_str.c_string() is only valid for the lifetime of port_str. Since that is allocated on the stack in initialize_port it becomes invalid once that function returns.
In your constructor, when you initialize the test3 string it ends up (mostly by chance) occupying the same memory as port_str did.
If you need to use a const char * you will need to allocate new memory for the string inside initialize_port (and deallocate it in your constructor!). Alternatively just stick with using std:string objects.

Related

Use a string as a char

I have been given this definitions, the function should return what is in info->phrase. However info->phrase can contain a string in which case I can only make it return the first char on info->phrase. Is there a way to make a string compatible with the char type? I am new to c++.
struct rep_info {
int num;
char *phrase;
};
I´ve tried few thing but get type errors, this was my latest attempt
char *phrase_info(rep_info info) {
char text[std::strlen(info->phrase) + 1];
text = info->phrase;
return text;
}
Since you said you have been given these definitions, let's fix the problem with the current setup first. Looking at your function, you are trying to copy into this local array (incorrectly I might add), and return this local variable. There are a number of things wrong with this, including the syntax and the fact that the local variable is destroyed when the function exits.
If you just need to get the value of the phrase member variable, the simplest solution would be to just access the member variable directly and return it:
char *phrase_info(rep_info info) {
return info.phrase; //since info is not a pointer, use the '.' accessor
}
If you mean to pass a pointer to the function, you would re-write it like this:
char *phrase_info(rep_info *info) {
return info->phrase;
}
But it seems like you feel the need to copy the contents of info->phrase into a new memory space? If so, then you would do something like this where you first allocate new memory and return this buffer:
char *phrase_info(rep_info *info) {
char *buf = new char[std::strlen(info->phrase) + 1];
std::strcpy(buf,info->phrase); //copies info->phrase into buf
return buf;
}
You would then need to use delete on the returned memory value to clean up the memory allocated by new, otherwise you will have a memory leak.
Overall, all the above solution would potentially solve the problem given some parameters you haven't made clear. To round this out, this should be written more like:
class rep_info {
private:
int num;
std::string phrase;
public:
rep_info(int n, std::string p) : num(n), phrase(p) {}
std::string get_phrase() { return phrase; }
// other functions
};
//later in the code
rep_info info(...);
info.get_phrase();
Ideally, you would wrap these member variables into their own object with corresponding member functions that can get and set these values. Moreover, for handling strings in C++, std::string is the preferred option for storing, copying, modifying, etc. strings over the older char * C-style string.

Subscripting a reference to const

I'm here looking at some C++ code and am not understanding something. It is irrelevant but it comes from a YARP (robot middleware) tutorial which goes with the documentation.
virtual void getHeader(const Bytes& header)
{
const char *target = "HUMANITY";
for (int i=0; i<8 && i<header.length(); i++)
{
header.get()[i] = target[i];
}
}
Now, header is a reference to const and thus cannot be modified within this function. get is called on it, its prototype is char *get() const;. How can header.get() be subscripted and modified ? The program compiles fine. I may have not understood what happens here but I'm basing myself on what I've read in C++ Primer...
I would very much appreciate a little clarification!
Have a nice day,
char *get() const;
The right hand const means "this member doesn't alter anything in the class that's not mutable", and it's honoring that - it isn't changing anything. The implementation is probably something like this:
char *Bytes::get() const
{
return const_cast<char *>(m_bytes);
}
The pointer that is being returned, however, is a simple "char*". Think of it this way:
(header.get())[i] = target[i];
// or
char* p = header.get();
p[i] = target[i];
Whoever designed the interface decided that the content of a const Byte object can be modified by stuffing values into it. Presumably they've done whatever hacks they needed to make header.get()[i] modifiable. I wouldn't use this code as an exemplar of good interface design.
Looking at the doc:
struct Bytes {
char* get() const; // works
char*& get() const; // would not work
char* mem_;
};
This code is perfectly valid, even though it is bad practice. The
problem is that a copy of the pointer is made and the constness of the
class is lost. constness in C++ is largely conceptual and easy to
break (often even without consequences). I'd complain to the
implementer. It should look like this:
struct Bytes {
char* get(); // works
const char* get() const; // would not work
char* mem_;
};
header.get() should returns char*, assuming it as base address and indexed with [i] and string in target coped to that location.
#antitrust given good point, return address can't be modified by address content can e.g.
char x[100];
char* get() const
{
return x;
}
int calling function you can do like:
get()[i] = target[i];
it will copy target string to x, this method can be useful when x is private member to class, and you are to copy in x.
Edit if get() is a inline function then calling get() function in a loop will not effect performance., I mean such function should be defined inline.

Empty string when trying to convert const char * to NSString

I have encountered a strange bug while trying to get a NSString from a const char *.
// in my obj c class
void myObjCMethod {
const char* charString = myCFunctionReturningConstCharPtr();
printf("%s \n", charString); // prints the correct string
// ...put a brakpoint here...
NSString * nsString1 = [NSString stringWithUTF8String:charString];
NSLog(#"%#", nsString1); // prints nothing
NSString * nsString2 = [NSString stringWithFormat:#"%s",charString];
NSLog(#"%#", nsString2); // prints nothing either
}
The const char coming from my c method prints nicely to the console. But trying to convert to NSString results in an empty string.
Now the weirdest thing is, that when I try to debug the code and set a breakpoint (as indicated above), my NSString suddenly becomes valid!
So what -- my mesurement changes the result? Sounds familiar from physics class long ago, but I doubt there is quantum mechanics involved here.
Note:
I have omitted the implementation of myCFunctionReturningConstCharPtr() for now, as it would add another layer of complexity that is probably not related to the present problem (There are multiple c++ libraries involved, the string has been converted from char pointer to std::string and back).
I've been banging my head against this for two days now, any help is appreciated very much! Thanks
EDIT:
The string initially comes from the struct SPODNode from PowerVR's Insider SDK.
There we have:
struct SPODNode {
PVRTchar8 *pszName;
// ...
}
With:
typedef char PVRTchar8;
In my code I do:
std::string MyCppClass::pvrNodeName() {
if (node && node->pszName) {
string stdName(node->pszName);
return stdName;
}
return string();
}
And finally in myCFunctionReturningConstCharPtr():
const char * myCFunctionReturningConstCharPtr() {
std::string stdString = myCppClassInstace->pvrNodeName()
return stdString.c_str();
}
I hope that helps!
The const char * is obtained by calling .c_str() on a std::string.
It is very likely that your program has Undefined Behavior, because you are returning a pointer to an array of character that gets deallocated when returning from function myCFunctionReturningConstCharPtr().
In fact, that const char* you return points to a character array that is encapsulated by a local std::string object; the destructor of the std::string object deallocates that array, and the destructor is invoked when the local object goes out of scope, i.e. when returning from the function.
Later attempts to dereference the pointer you receive result in Undefined Behavior, which means anything could happen. This includes your program seeming to run fine when being debugged, but not when running without the debugger attached.
You should have your function return (by value) an std::string, and then invoke c_str() on that returned value if you need to get the encapsulated C-string:
std::string charString = myCFunctionReturningConstCharPtr();
printf("%s \n", charString.c_str()); // prints the correct string

how to set char * value from std string (c_str()) not working

i dont know but this not working for me im getting garbege value when i try to set char * value from function that returns std string :
string foo()
{
string tmp ="dummy value";
return tmp;
}
char* cc = (char *) foo().c_str(); // if i remove the casting im getting error
// when i print the cc i get garbage
printf("%s",cc);
The lifetime of the data pointed to by cc is the same as the lifetime of the string it came from (at best - if you modify the string it's even shorter).
In your case, the return value of foo() is a temporary that is destroyed at the end of the initialization of cc.
To avoid the compilation error in char *cc = foo().c_str() you shouldn't cast to char*, you should switch to const char *cc, since const char* is what c_str() returns. That still doesn't solve the main problem, though.
The simplest fixes are:
printf("%s", foo().c_str()); // if you don't need the value again later
const string s = foo();
const char *cc = s.c_str(); // if you really want the pointer - since it's
// in the same scope as s, and s is const,
// the data lives as long as cc's in scope.
string s = foo();
printf("%s", s.c_str()); // if you don't store the pointer,
// you don't have to worry about it.
std::cout << foo(); // printf isn't bringing much to this party anyway.
The result of foo is a temporary object that gets destroyed by the end of char * cc = ... line. Store it in constant reference:
const string& cc = foo();
printf ("%s", cc.c_str());
Pass a memory location to foo() and have foo modify that:
void foo (string* _out_newStr)
{
_out_newStr->assign("dummy string"); //This is wrong -> _out_newStr = "dummy string";
return;
}
Then when you are using the "c_str()" function of the string object you will return a const char* value, as already pointed out.
The code-snippet invokes undefined behavior, because the temporary std::string created from the call is destroyed at the end of the expression but cc which is pointing to the destroyed object, is still used even after that.
How about:
printf("%s", foo.c_str() );
Or better still, forget about using character pointers.

const char* in my class has junk character(s) after it's returned from function

Class:
class myclass {
public:
myclass(void);
const char* server;
private:
char pidchar[6];
int pidnum;
};
The function
myclass parseINI(const char* file)
{
myclass iniOptions;
CSimpleIniA ini;
ini.SetUnicode();
ini.LoadFile(file);
const char* server = ini.GetValue("", "server", "");
iniOptions.server = server;
std::cout << server << "\n"; // Prints the correct value here
fflush(stdout);
return iniOptions;
}
Calling it from the main function
int _tmain(int argc, TCHAR* argv[])
{
myclass options;
options = parseINI("myapp.ini");
std::cout << options.server << "\n"; // It prints junk here
return 0;
}
What did I do wrong?
The const char* returned by GetValue() probably belonged to the ini object. When you exited the parseIni() function, ini went out of scope and was destroyed, which could mean your pointer is no longer valid.
Try using a std::string for the server member type instead of const char*.
It looks like you are using memory that is released when CSimpleIniA goes out of scope in parseINI.
const char* server = ini.GetValue("", "server", "");
iniOptions.server = server;
Copy the value that is returned into a new memory block before you return from the parseINI function.
string server = ini.GetValue("", "server", "");
iniOptions.server = new char[server.length() + 1];
std::copy(server.begin(), server.end(), iniOptions.server);
iniOptions.server[server.length()] = 0;
const char* server = ini.GetValue("", "server", "");
This value is falling out of scope when the function terminates, so when you assign the value of that pointer to your object's server pointer, the place in memory they point to is having its memory freed off the stack at the end of the function, and it's then overtaken by other things.
Using a std::string or even just a char[] will be preferred to just fix the problem with the least amount of changes, as they will by assigned the actual value and not a location in memory like pointers.
What you really should do is look up referential transparency, though. That will prevent problems like this from occurring ever again
I's guess that the lifetime of the data pointed to by the char* returned from CSimpleIniA::GetValue() is the same as the CSimpleIni object itself. So when ini is destructed, the pointer returned from GetValue() becomes invalid. (I've never used CSimpleIni, and haven't looked at the docs carefully enough to know for sure, but that's what the behavior points to).
I'd suggest changing myclass::server to be a std:string object and set it using something like:
iniOptions.server = std::string(server);
which will give the myclass::server object it's own copy of the string data.
The way you are using class as a function returned data type in C++ is totally wrong.
In C++ there are 2 kinds of data type: value type, reference type.
class belongs to second one; From a function you can return a value type data or a pointer of any data.But you cann't retun a entity of a reference type. Because a entity of a reference type will be released right after the code reached out of the scope which the entity is defined.
You can do in either way:
1:
define parseINI as:
myclass* parseINI(const char* file)
{
myclass* iniOptions = new myclass();
........
return iniOptions;
}
and then use it like this:
myclass* options = parseINI("myapp.ini");
2:
define parseINI as:
void parseINI(myclass& options, const char* file)
{
........//asigne value to options's members
}
and then use it like this:
myclass options;
parseINI(options,"myapp.ini");
3:
Do what you did, but add a asignment method (operator=) to myclass
The problem is that the local variable server points to a character buffer returned by ini.GetValue(), which is destroyed when paraseINI() returns.
One way to fix this is to allocate a new buffer yourself and copy the characters.
const char* server = ini.GetValue("", "server", "");
int length = strlen(server) + 1; // length of the string +1 for the NULL character.
delete [] iniOptions.server; // free the old buffer
iniOptions.server = new char[length]; // allocate your own buffer
strncpy(iniOptions.server, server, length); // copy the characters
For this to work you have to make myclass::server non-const, and you have to initialize it to NULL in the constructor and delete it in the destructor.
A better way to deal with this situation would be use std::string instead of char * for muclass::server. This way std::string would take care of memory management for you, and the code would be exception-safe.
If you make muclass::server an std::string, then you simply do
const char* server = ini.GetValue("", "server", "");
iniOptions.server = std::string(server);
And you do not have to do anything with it in the constructor or the destructor.
iniOptions is located on the stack and disposed automatically when the function returns. You should allocate it on heap using new()