CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 18
  1. #1
    Join Date
    Apr 2001
    Posts
    1,029

    [RESOLVED] question about memcpy, char* and string

    Hello,

    I have the following code that works fine for packing and unpacking with memcpy:

    #include <string>
    using namespace std;

    Code:
    int main()
    {
        // PACK
        char *bufptr; 
        char buf[12];
        unsigned int data1 = 1003;
        unsigned int data2 = 0;
        float data3 = 90.0;
        bufptr = buf; 
        memcpy(bufptr, &data1, 4);
        bufptr+=4;
        memcpy(bufptr, &data2, 4);
        bufptr+=4;
        memcpy(bufptr, &data3, 4);
        bufptr+=4;
    
        // UNPACK
        unsigned int _data1, _data2;
        float _data3;
        char *temp = buf;
        memcpy(&_data1, temp, 4); 
        temp+=4;
        memcpy(&_data2, temp, 4); 
        temp+=4;    
        memcpy(&_data3, temp, 4); 
        temp+=4; 
        return 0;
    }

    but now I tried to add strings into the mix, and it stops working. What am I doing wrong with the strings here?

    #include <string>
    using namespace std;

    Code:
    int main()
    {
        // PACK
        char *bufptr; 
        char buf[12];
        unsigned int data1 = 1003;
        unsigned int data2 = 0;
        float data3 = 90.0;
        bufptr = buf; 
        memcpy(bufptr, &data1, 4);
        bufptr+=4;
        memcpy(bufptr, &data2, 4);
        bufptr+=4;
        memcpy(bufptr, &data3, 4);
        bufptr+=4;
        string message=buf;
    
        // UNPACK
        unsigned int _data1, _data2;
        float _data3;
        char *temp = (char*)message.c_str();
        memcpy(&_data1, temp, 4); 
        temp+=4;
        memcpy(&_data2, temp, 4); 
        temp+=4;    
        memcpy(&_data3, temp, 4); 
        temp+=4; 
        return 0;
    }

    I am guessing trhe line that is wrong is this line:

    char *temp = (char*)message.c_str();

    Can anyone help me to make this work correctly with strings?

    Thanks!!

  2. #2
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: question about memcpy, char* and string

    Quote Originally Posted by lab1
    Can anyone help me to make this work correctly with strings?
    You could probably make it work. But it is a bad idea to keep binary data in strings because all internal functions that need to determine its size will look for a first 0 byte...
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  3. #3
    Join Date
    Jul 2007
    Location
    Richmond, BC
    Posts
    79

    Re: question about memcpy, char* and string

    There is nothing wrong with
    Code:
    char *temp = (char*)message.c_str();
    All 'magic' happens here
    Code:
     string message=buf;
    You initialize string object with c-string (which is 0-terminated string), so as soon as the first 0 occurs in buf, the process is stopped. I'd suggest that vector<char> is more natural type in this case.
    Last edited by a1ex07; June 23rd, 2008 at 02:55 PM.

  4. #4
    Join Date
    Apr 2001
    Posts
    1,029

    Re: question about memcpy, char* and string

    Hey Alex,

    How can I fix this then? How do I copy a char buffer into a string?

    Thanks!

  5. #5
    Join Date
    Apr 2001
    Posts
    1,029

    Re: question about memcpy, char* and string

    Hey Alex,

    What if I must use a string? is there any possible way to initial a string with a char buffer?

    Thanks!
    Curtis

  6. #6
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,637

    Re: question about memcpy, char* and string

    Quote Originally Posted by lab1
    Hey Alex,

    How can I fix this then? How do I copy a char buffer into a string?

    Thanks!
    As has been pointed out, a string is not the right data type if your data contains embedded nulls.

  7. #7
    Join Date
    Apr 2001
    Posts
    1,029

    Re: question about memcpy, char* and string

    Sorry but I think you are wrong. Here is some example code:

    Code:
        char buffer[14] = "testtest0test";
        char buffer2[14];
        string message=buffer;
        char *temp = (char*)message.c_str();
        memcpy(&buffer2, temp, 14);

    or is this "0" not an embedded null?

    Thanks

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: question about memcpy, char* and string

    Quote Originally Posted by lab1
    Hey Alex,

    What if I must use a string? is there any possible way to initial a string with a char buffer?
    Have you tried looking at all of the constructors that string takes?

    http://www.sgi.com/tech/stl/basic_string.html

    Code:
    #include <string>
    
    int main()
    {
       std::string s("abc123", 4);
    }
    In other words, a string buffer as the first parameter, and the number of bytes to use from the buffer is the second parameter.

    Regards,

    Paul McKenzie

  9. #9
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,637

    Re: question about memcpy, char* and string

    Quote Originally Posted by lab1
    Sorry but I think you are wrong. Here is some example code:

    Code:
        char buffer[14] = "testtest0test";
        char buffer2[14];
        string message=buffer;
        char *temp = (char*)message.c_str();
        memcpy(&buffer2, temp, 14);

    or is this "0" not an embedded null?

    Thanks
    No, it's not a null.

  10. #10
    Join Date
    Jul 2007
    Location
    Richmond, BC
    Posts
    79

    Re: question about memcpy, char* and string

    You can use vector<char> instead of string
    Code:
    #include <vector>
    int main()
    {
       // PACK
        char buf[12];
        unsigned int data1 = 1003;
        unsigned int data2 = 0;
        float data3 = 90.0;
        bufptr = buf; 
        memcpy(bufptr, &data1, 4);
        bufptr+=4;
        memcpy(bufptr, &data2, 4);
        bufptr+=4;
        memcpy(bufptr, &data3, 4);
        bufptr+=4;
        //string message=buf;
    
        std::vector<char> message1(12);
        memcpy(&message1[0],buf,12);
    
        // UNPACK
        unsigned int _data1, _data2;
        float _data3;
        //char *temp = (char*)message.c_str();
       char *temp = &message1[0];
    
        memcpy(&_data1, temp, 4); 
        temp+=4;
        memcpy(&_data2, temp, 4); 
        temp+=4;    
        memcpy(&_data3, temp, 4); 
        temp+=4; 
        return 0;
       // UNPACK
    You can also get rid of all char* variables and change it to :
    Code:
    
       vector<char> buffer(12);
        unsigned int data1 = 1003;
        unsigned int data2 = 0;
        float data3 = 90.0;
       // Pack
        memcpy(&buffer[0], &data1, 4);
        memcpy(&buffer[4], &data2, 4);
        memcpy(&buffer[8], &data3, 4);
    
       // Unpack
        memcpy(&_data1, &buffer[0], 4); 
        memcpy(&_data2, &buffer[4], 4); 
        memcpy(&_data3, &buffer[8], 4);

  11. #11
    Join Date
    Apr 1999
    Posts
    27,449

    Re: question about memcpy, char* and string

    Quote Originally Posted by GCDEF
    As has been pointed out, a string is not the right data type if your data contains embedded nulls.
    It can be the right data type, if you use the correct functions.

    For example, std::string::append(), the correct constructor (which is not what lab1 was using), etc.

    If you wish to change the data in place, then a better choice would be vector<char> (but that is also bound to change, since the standards committee has just specified that the contents of std::string are changeable and contiguous, exactly like an array).

    Regards,

    Paul McKenzie

  12. #12
    Join Date
    Jul 2007
    Location
    Richmond, BC
    Posts
    79

    Re: question about memcpy, char* and string

    If you have to stick to string, you can do
    Code:
     //...
      string message;
      message.resize(12);
      for (int i = 0; i<12; i++)
      {
         message[i] = *(buf+i);
      }
    I'm not sure how safe it is though...

  13. #13
    Join Date
    Apr 1999
    Posts
    27,449

    Re: question about memcpy, char* and string

    Quote Originally Posted by a1ex07
    If you have to stick to string, you can do
    Code:
     //...
      string message;
      message.resize(12);
      for (int i = 0; i<12; i++)
      {
         message[i] = *(buf+i);
      }
    You don't need that at all. Did you read my previous message?
    Code:
    string message(buf, 12);
    That's all you need to do.

    Regards,

    Paul McKenzie

  14. #14
    Join Date
    Feb 2002
    Posts
    4,640

    Re: question about memcpy, char* and string

    Quote Originally Posted by a1ex07
    There is nothing wrong with
    Code:
        char *temp = (char*)message.c_str();
        memcpy(&_data1, temp, 4); 
        temp+=4;
        memcpy(&_data2, temp, 4); 
        temp+=4;    
        memcpy(&_data3, temp, 4); 
        temp+=4;
    I'm sorry, but this is incorrect! 'c_str()' returns a const char *, casting away the const and modifying the buffer is undefined behavior.

    Viggy

  15. #15
    Join Date
    Jul 2007
    Location
    Richmond, BC
    Posts
    79

    Re: question about memcpy, char* and string

    I'm sorry, but this is incorrect! 'c_str()' returns a const char *, casting away the const and modifying the buffer is undefined behavior.
    The original code doesn't change buffer; removing const attribute by itself cannot cause any problem. For sure,
    Code:
    char  const* temp = message.c_str();
    looks better, but it's not an issue in this case.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured