What's the difference between char * and const_cast<char*>(string.c_str())
Asked Answered
D

3

5

I use an external library to deal with udp (OSC) communication between 2 apps. To format the messages that will be sent, the library is expecting a char* but I get a string from the UI that I have to convert.

While I was dealing with other parts of my code the udp part was hard coded like that :

    char* endofMess = "from setEndMess"; 

and was working fine. I thought it would be easy to get it working with my strings and wrote :

    std::string s = "from setEndMess";
    char* endofMess = const_cast<char*>(s.c_str());

but unlike for the first example where I was receiving the message correctly formatted, I now receive only gibberish characters. Does somebody know where it can come from?

Thanks!

Matthieu

EDIT : the code I use : The method to send the message each time OSCVal will change :

void osc500::testOSC(int identifier, float OSCval)
{
UdpTransmitSocket transmitSocket( IpEndpointName( destIP, port ) );
 char buffer[1024];
 osc::OutboundPacketStream p( buffer, 1024 );

p << osc::BeginBundleImmediate
    << osc::BeginMessage( endofMess )
       << OSCval << osc::EndMessage
<< osc::EndBundle;


transmitSocket.Send( p.Data(), p.Size() );
}

And if I have to change the OSC pattern I call this one :

void osc500::setEndMess(String endpattern){
// endofMess = "from setEndMess"; //OK works fine each time it's called

//1st try :
//std::string s = "from setEndMess"; 
//endofMess = const_cast<char*>(s.c_str()); //gibberish    

//2nd try :
//std::string s = "from setEndMess";
//endofMess = &s[0]; //gibberish    

//3rd & 4th tries :
//char s[4] = {'t','e','s','t'}; 
//char s[5] = {'t','e','s','t','\0'};
//endofMess = s; //gibberish    
}
Doubleminded answered 18/11, 2012 at 10:36 Comment(4)
It's not clear whether you're trying to save things to that char* or if you're passing that to a network function for it to be sent on the wire.Janiculum
It's to change a variable in a function that will say how the message is formatted ex : to change messages from "/firstOSCpattern/ x" to "/secondOSCpattern/ x"Doubleminded
Add more information to your question by editing it (there's a link for that right under the tags). Don't past code in comments, it's impossible to format.Janiculum
@Mat, I just figured it out! :) The problem was what Yakk pointed! Thanks a lot to every one of you, I really appreciated your help, I was kind of desperate!Doubleminded
L
3

I suspect the char* is not written to, it is only non const because it is a legacy API. If so, your problem is probably that the std::string has fallen out of scope or been modified between the point where you call c_str and where it is used in the guts of the API.

Lianneliao answered 18/11, 2012 at 11:4 Comment(0)
M
4

c_str() is for read-only access of std::string.

If you want to write to a string through pointers, then use either...

  1. an array (or vector) of char instead of std::string
  2. char* buf = &str[0]; - point directly to the first character of a string

Trick (2) is guaranteed to work under C++11; in practice it works in C++03 too but that relies on compiler implementation of std::string having contignuos storage.

(And whatever you do, keep an eye on the buffer length.)

Magdaleno answered 18/11, 2012 at 10:44 Comment(0)
L
3

I suspect the char* is not written to, it is only non const because it is a legacy API. If so, your problem is probably that the std::string has fallen out of scope or been modified between the point where you call c_str and where it is used in the guts of the API.

Lianneliao answered 18/11, 2012 at 11:4 Comment(0)
F
1

If you want to modify the std::string content, I think you should use &s[0] (making sure that the string is big enough).

std::string s = "abcdef...";
char* ptr = &s[0];

e.g. (tested with MSVC10):

#include <iostream>
#include <ostream>
#include <string>

using namespace std;

void f(char* ptr, size_t count)
{
    for (size_t i = 0; i < count; i++)
        ptr[i] = 'x';
}

int main()
{
    string s = "abcdef";
    cout << s << endl;

    f(&s[0], 3);
    cout << s << endl;    
}

Output:

abcdef
xxxdef
Fountainhead answered 18/11, 2012 at 10:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.