1

我有以下问题。我使用以下函数从缓冲区接收字符串,直到出现换行符。

string get_all_buf(int sock) {
    int n = 1, total = 0, found = 0;
    char c;
    char temp[1024*1024]; 
    string antw = "";

    while (!found) {
        n = recv(sock, &temp[total], sizeof(temp) - total - 1, 0);
        if (n == -1) {

            break;
        }
        total += n;
        temp[total] = '\0';
        found = (strchr(temp, '\n') != 0);

        if (found == 0){
        found = (strchr(temp, '\r\n') != 0);
        }
    }
    antw = temp;

    size_t foundIndex = antw.find("\r\n");
    if (foundIndex != antw.npos)
    antw.erase ( antw.find ("\r\n"), 2 );

    foundIndex = antw.find("\n");
    if (foundIndex != antw.npos)
    antw.erase ( antw.find ("\n"), 2 );

    return answ;
}

所以像这样使用它:

string an = get_all_buf(sClient);

如果我创建一个 exe 文件,一切正常。但是,如果我创建一个 dll 并使用 rundll32 运行它,则应用程序将在“ string an = get_all_buf(sClient);”处关闭而没有任何错误消息......

我试图解决这个问题已经好几个小时了,我现在有点绝望......

PS 对明显的错误或糟糕的编码风格表示抱歉,我刚开始学习 C++。

4

2 回答 2

3
char temp[1024*1024]; 

在堆栈上声明一个 1Mb 的结构。这可能太大并溢出可用的堆栈内存。你可以改为给它静态范围

static char temp[1024*1024]; 

或动态分配

char* temp = (char*)malloc(1024*1024);
// function body
free(temp);

或者,假设提到 run32.dll 意味着您在 Windows 上工作,您可以使用/STACK链接器选项调查将其保留在堆栈中。这可能不是最好的方法——您已经发现,当您更改构建设置或尝试针对其他平台时,它会导致问题。

于 2013-03-01T10:55:12.537 回答
1

我不是在堆栈上创建temp变量,而是动态地(在堆上)创建它,但不使用 rawmallocfree如上一个答案所示,而是使用现代 C++ 和std::vector

#include <vector>

std::vector<char> temp(1024*1024);

这是异常安全的,您不必注意释放分配的内存:std::vector的析构函数会自动执行此操作(在抛出异常的情况下也是如此)。

而不是sizeof(temp), 在您的代码中,您可以使用temp.size()(它将返回向量中元素的计数,并且由于这是chars 的向量,因此它将仅返回以chars 为单位的总向量大小,即以字节为单位)。

您仍然可以使用operator[]for std::vector,就像对原始 C 数组所做的那样。

另请注意,如果您正在构建一个DLL,并且上述函数在 DLL 接口处公开,因为该函数有一个C++ 接口,std::string边界处有一个 STL 类 (),您必须注意您的 DLL 和您的客户端都是构建的具有到相同 CRT的动态链接,以及相同的编译器相同的编译器设置(例如,您不能将使用 VS2008/VC9 构建的 DLL 与使用 VS2010/VC10 构建的 .EXE 或带有debug-build EXE 使用相同的编译器构建)。

于 2013-03-01T11:27:29.133 回答