0

如果这很愚蠢,请原谅我,但我对 C/C++ 比较陌生。

在我正在创建的套接字库中,我的 ClientSocket::recv(int bufsize) 函数使用 'bufsize' 来初始化一个 char[] 数组以从 C 套接字读取。使用 G++ 编译的代码可以正常工作。

我遇到的问题是一些正在编译我的代码的人收到以下错误: socket.cxx||In member function ‘std::string ClientSocket::recv(int)’:| socket.cxx|269|error: ISO C++ forbids variable length array ‘buffer’|

现在,从我在这个论坛上读到的内容来看,微软只支持 C89,而 GCC 支持 C99,其中可以接受可变大小的数组。同样在该线​​程上,他们建议使用 _alloca() - 问题是,它最多支持 1mb。我宁愿没有限制。

如果这是使它与 GCC/MSVC++ 交叉编译的唯一可能方法,我想我将不得不忍受它。很高兴知道一个替代方案。像 malloc() 这样的东西会起作用吗?(以前从未使用过,所以我不知道)如果是这样,您能告诉我如何使用它或链接到教程/文档吗?谢谢!

PS:这是我的 recv() 函数的代码:

std::string ClientSocket::recv(int bufsize) {

    // isConnected() is a ClientSocket function
    if (!isConnected()) throw SocketException("Not connected.");

    char buffer[bufsize+1];

    // I did this because sometimes it was returning partial garbage :\
    memset(buffer, 0, bufsize);

    // the :: prefix means to call the recv() from the header files instead of ClientSocket::recv()
    int ret = ::recv(sockfd, buffer, bufsize-1, 0);

    if (ret < 0) {
        switch(errno) {
            case ECONNREFUSED:
                throw SocketException("Connection refused on recover.");
                break;
            case ENOTCONN:
                throw SocketException("Not connected.");
                break;
            default:
                throw SocketException("Unknown error reading socket.");
                break;
        }
    } else if (ret == 0) {
        // we got disconnected, return empty string. (connected is a protected variable of ClientSocket)
        connected = false;
        return "";
    }

    return buffer;
}

编辑:根据建议,我计划使用vector buffer(bufsize+1, 0); ... recv(sockfd, &buffer[0], bufsize, 0); ... return &buffer[0];OR char *buffer = new char[bufsize + 1]; memset(buffer, 0, bufsize); ... recv(sockfd, buffer, bufsize, 0); ... string tmp = buffer; delete [] buffer; return string(tmp);- 仍然安装 MSVC++ 以对其进行测试,但我相信它会起作用。太感谢了!StackOverflow 摇滚!

4

4 回答 4

7

g++ 允许 C++ 中的 C99 可变长度数组作为语言扩展。

标准 C++ 不支持它们。

在 C++ 中使用 astd::vectorstd::string.

干杯&hth.,

于 2011-03-13T21:25:03.210 回答
0

尝试这样做:

char * buffer = new char[bufsize + 1];

于 2011-03-13T21:26:02.453 回答
0

我会创建一个简单的缓冲区类来包装一个char *来处理这个问题。它将new用于分配缓冲区。我相信也可以使用 avector并且仍然符合标准。但我不完全确定如何以推荐的方式进行。

于 2011-03-13T21:30:48.803 回答
0

您甚至不需要使用 memset,如果您使用的是 gcc 或 g++,您实际上可以使用 char 类型上的常规聚合将其全部分配为零,请考虑:

char * buffer[bufsize+1] = {0};

这段代码只能在 gcc/g++ 中工作,因为 gcc 允许在堆栈上使用可变大小的数组。

您唯一的其他选择是使用:

char * buffer = new char[bufsize+1];
// and assign it zeros with std::fill
std::fill(buffer, buffer+bufsize+1, 0); 
于 2011-03-14T03:03:54.263 回答