我有这个结构:

  struct          __attribute__((packed)) BabelPacket
  {
    unsigned      senderId;
    unsigned      dataLength;
    unsigned char data[0];
  };

并声明我这样做:
  BabelPacket *packet = reinterpret_cast<BabelPacket *>(new char[sizeof(BabelPacket) + 5]);
  packet->senderId = 1;
  packet->data = "kappa";
  packet->dataLength = 5;

但是当我编译的时候我有这个错误:
error: incompatible types in assignment of ‘const char [6]’ to ‘unsigned char [0]’
   packet->data = "kappa";

            ^

你知道我该怎么做吗?
而且我需要通过套接字发送此结构,以将对象恢复到服务器中,因此我只能使用C类型。

最佳答案

如果您愿意/允许将unsigned char更改为常规char,则可以使用strcpy:

#include <iostream>
#include <stdio.h>
#include <string.h>

struct          __attribute__((packed)) BabelPacket
{
  unsigned      senderId;
  unsigned      dataLength;
  char data[0]; // I changed this to char in order to use strcpy
};

int main(){
  BabelPacket *packet = reinterpret_cast<BabelPacket *>(new char[sizeof(BabelPacket) + 5]);
  packet->senderId = 1;
  // Copy the string. Add NULL character at the end of
  // the string to indicate its end
  strcpy(packet->data, "kappa\0");
  packet->dataLength = 5;

  // Verify that the string is copied properly
  for (int i=0;i<packet->dataLength;++i){
    std::cout<<packet->data[i];
  }
  std::cout<<std::endl;

  return 0;
}

请注意,这仅在data位于struct的末尾时才起作用,否则,就没有连续的内存来分配data。如果我将元素的顺序交换为:
struct          __attribute__((packed)) BabelPacket
{
  unsigned      senderId;
  char data[0]; // I changed this to char in order to use strcpy
  unsigned      dataLength;
};

上面代码的输出(而不是“kappa”)将是“a”。

如果确定要使用C数组,一种更可靠的方法是假设最大数量的元素并预分配数组,即:
#include <iostream>
#include <stdio.h>
#include <string.h>

#define MAX_NUMBER_OF_CHARACTERS 5 // Many ways to do this, I defined the macro for the purposes of this example

struct          __attribute__((packed)) BabelPacket
{
  unsigned      senderId;
  // I changed this to char in order to use strcpy. Allocate the
  // max number + 1 element for the termination string
  char data[MAX_NUMBER_OF_CHARACTERS+1];
  unsigned      dataLength;
};

int main(){
  BabelPacket *packet = reinterpret_cast<BabelPacket *>(new char[sizeof(BabelPacket) + 5]);
  packet->senderId = 1;
  packet->dataLength = 5;
  if (dataLength>MAX_NUMBER_OF_CHARACTERS){
    std::cout<<"String greater than the maximum number of characters"<<std::endl;
  }
  // Copy the string. Add NULL character at the end of
  // the string to indicate its end
  strcpy(packet->data, "kappa\0");

  // Verify that the string is copied properly
  for (int i=0;i<packet->dataLength;++i){
    std::cout<<packet->data[i];
  }
  std::cout<<std::endl;

  return 0;
}

此代码产生正确的输出,并保护您免受违规。如您所见,它很快就会变得困惑,这就是为什么我建议为此使用std::vector的原因。然后可以按照 vector 的大小自动检索dataLength,并且始终可以防止溢出。

关于c++ - 如何声明未知大小的结构?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40083374/

10-11 23:05
查看更多