3

我正在尝试用 C++ 编写一个程序,该程序将接受来自服务器上客户端的消息。但首先,客户端发送消息的大小,并使用该值,服务器将创建一个字符数组来存储最终发送的消息。当我尝试使用消息大小值初始化数组时,编译器说存在错误,因为 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);
}
4

5 回答 5

3

在 C++ 中——请注意,我们谈论的是没有扩展的一致 C++——自动数组分配的大小在编译时已知,因为数组的大小必须在编译时知道。

因此,这段代码:

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;
于 2013-10-11T18:29:34.467 回答
2

要扩展John Diblings 的答案,您应该使用 anstd::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通过调用以 asize_type作为参数的构造函数来初始化正确的大小。要将缓冲区传递给revc您,只需获取std::vector.

于 2013-10-11T18:52:27.860 回答
0

您应该只声​​明一个大小可以在编译时解释的数组。即,它应该是int文字 ( char bufferMessDNS [100]) 或使用宏 (如#define MSG_SIZE 100) 或const int.

出于您的目的,因为您只会在运行时知道您可以使用的大小

char *bufferMessDNS = new char[messageSize];
....
delete []bufferMessDNS
于 2013-10-11T18:30:14.393 回答
0

问题是,编译器需要知道在编译时在堆栈上创建的所有变量的大小 -> 您只能分配在编译时已知大小的数组

如果仅在运行时知道大小,则可以使用动态内存分配。IE:

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;

有关为什么编译器必须在编译时知道堆栈变量的大小的详细答案,请参阅这篇文章: 为什么 C/C++ 编译器需要在编译时知道数组的大小?

于 2013-10-11T19:12:25.810 回答
-1

这是一个非常严格的 C 编译器吗?也许您只需要将声明与初始化分开?

int messageSize;
messageSize = dnsStyle();
于 2013-10-11T18:11:22.557 回答