我正在尝试用C ++编写一个程序来接受来自服务器上客户端的消息。但首先,客户端发送消息的 size ,并使用此值,服务器将创建一个chars数组,以便在最终发送消息时存储消息。当我尝试使用消息大小值初始化数组时,编译器说有一个错误,因为messageSize整数必须是一个常量值 - 我想知道为什么会发生这种情况,因为据我所知,初始化是完全可以接受的具有整数类型的数组的长度:
//Deal with data in DNS style
int dnsStyle()
{
recv(clientSocket, bufferSize, 1, MSG_WAITALL);
return bufferSize[0];
}
//Communicate in the DNS style of addressing
char DNS()
{
int messageSize = dnsStyle();
printf("The message buffer has been tailoured to this size: '%d'", messageSize);
char bufferMessDNS[messageSize];
//Then recieve the actual message itself
recv(clientSocket, bufferMessDNS, messageSize, MSG_WAITALL);
//Then send the message back to client
send(clientSocket, bufferMessDNS, messageSize, 0);
//std::string returnMess = "OK";
//send(clientSocket, sendBack.c_str(), sendBack.size(),0);
}
答案 0 :(得分:3)
在C ++中 - 并且,请注意,我们讨论的是没有扩展的符合条件的C ++ - 在编译时分配自动数组的大小,因为在编译时必须知道数组的大小。 / p>
因此,这段代码:
char bufferMessDNS[messageSize];
格式不正确,因为messageSize
可能会发生变化。
如果您需要不同大小的数组,请使用vector <char>
。
如果你使messageSize
成为所谓的积分常量表达式,你可以使上面的代码工作,如下所示:
const size_t messageSize = 256;
char bufferMessDNS[messageSize];
但是这里缓冲区的大小总是精确到256字节 - 我相信它几乎不会是正确的大小。
如果必须,您还可以使用new[]
:
char* bufferMessDNS = new char [messageSize]
但这会打开一大堆新问题,其中最重要的是管理你刚刚分配的内存的所有权。现在你需要delete
:
delete [] bufferMessDNS;
答案 1 :(得分:2)
要展开John Diblings answer,您应该使用std::vector<char>
作为缓冲区。这是它的工作原理:
char DNS()
{
std::vector<char>::size_type messageSize = dnsStyle(); // use correct type
printf("The message buffer has been tailoured to this size: '%d'", messageSize);
std::vector<char> bufferMessDNS(messageSize); // create vector with correct size
//Then recieve the actual message itself
recv(clientSocket, &bufferMessDNS[0], messageSize, MSG_WAITALL);
//Then send the message back to client
send(clientSocket, &bufferMessDNS[0], messageSize, 0);
//std::string returnMess = "OK";
//send(clientSocket, sendBack.c_str(), sendBack.size(),0);
}
这里最重要的部分是通过调用以std::vector
为参数的构造函数来初始化具有正确大小的size_type
。要将缓冲区传递给revc
,您只需要获取std::vector
的第一个元素的地址。
答案 2 :(得分:0)
您应该声明一个数组,其大小只能在编译时解释。即,它应该是int
文字(char bufferMessDNS [100]
)或使用宏(如#define MSG_SIZE 100
)或const int
。
出于您的目的,因为您;只有在运行时才知道尺寸,您可以选择
char *bufferMessDNS = new char[messageSize];
....
delete []bufferMessDNS
答案 3 :(得分:0)
问题是,编译器需要知道在编译时在堆栈上创建的所有变量的大小 - &gt;你只能在编译时分配已知大小的数组
如果仅在运行时知道大小,则可以使用动态内存分配。 即:
char bufferMessDNS[messageSize];
// replace with
char* bufferMessDNS = new char[messageSize];
// and at the end of your function don't forget to release the memory
delete[] bufferMessDNS;
详细解答为什么编译器必须在编译时知道堆栈变量的大小,请参阅以下文章: Why does a C/C++ compiler need know the size of an array at compile time?
答案 4 :(得分:-1)
这是一个非常严格的C编译器吗?也许你只需要将你的声明与初始化分开?
int messageSize;
messageSize = dnsStyle();