1

I need to save packet state for a while. So I read the packet data which is represented as unsigned char* and than I create a record with this data and save the record in the list for a while.

Which will be a better way to represent the packet in the record as char* or as char[].

How do i copy the read data ( unsigned char ) to both options : To unsigned char[] and to unsigned char*

I need to copy the data because each time I read packet it will be readed to the same char*,so when I save it for a while I need to copy data first

Avihai Marchiano
  • 3,837
  • 3
  • 38
  • 55

2 Answers2

10

If the packet data is binary I'd prefer using std::vector to store the data, as opposed to one of the C strXXX functions, to avoid issues with a potential NULL character existing in the data stream. Most strXXX functions look for NULL characters and truncate their operation. Since the data is not a string, I'd also avoid std::string for this task.

std::vector<unsigned char> v( buf, buf + datalen );

The vector constructor will copy all the data from buf[0] to buf[datalen - 1] and will deallocate the memory when the vector goes out of scope. You can get a pointer to the underlying buffer using v.data() or &v[0].

Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • 8
    Oh look, a person who knows C++. – Cat Plus Plus Aug 05 '12 at 16:24
  • 1
    Personally I wouldn't suggest using `strXXX` functions in C++ under **any** circumstances (well there might be a few where, but still) – Grizzly Aug 05 '12 at 16:29
  • My list is list of record . One of the field in record is this char array. – Avihai Marchiano Aug 05 '12 at 16:31
  • @user1495181 By *record* I assume you mean you have a list of `struct`s or `class`es. Just change the type of the `unsigned char *` field in the structure to an `std::vector`. – Praetorian Aug 05 '12 at 16:34
  • 1
    I am not sure if this is just an artifact of how the answer has been written, but while the *C* `strXXX` functions cannot deal with nested null characters, `std::string` has no problems at all. The choice of `std::vector` vs. `std::string` should be taken on the grounds that if it is not a string, the extra richness of the `std::string` interface is unneeded. Additionally, depending on the domain, an *array* (`std::array`), or a real structure with a nested C-style array might be a good (or even better) solution that does not require extra allocations (specially in C++03) – David Rodríguez - dribeas Aug 05 '12 at 16:43
  • @DavidRodríguez-dribeas Thanks for pointing that out, it does sound as if `std::string` should not be used because of the same issues as the `strXXX` functions. Fixed now. – Praetorian Aug 05 '12 at 16:48
-3

So, it sounds like you need to save the data from multiple packets in a list until some point in the future.

If it was me, I'd use std::string or std::vector normally because that removes allocation issues and is generally plenty fast.

If you do intend to use char* or char[], then you'd want to use char*. Declaring a variable like "char buf[1024];" allocates it on the stack, which means that when that function returns it goes away. To save it in a list, you'd need to dynamically allocate it, so you would do something like "char *buf = new char[packet.size];" and then copy the data and store the pointer and the length of the data in your list (or, as I said before, use std::string which avoids keeping the length separately).

How do you copy the data?

Probably memcpy. The strcpy function would have problems with data which can have nul characters in it, which is common in networking situations. So, something like:

char *buf = new char[packet_length];
memcpy(buf, packet_data, packet_length);
// Put buf and packet_length into a structure in your list.
cds
  • 95
  • 6