一旦位置接近100KB,就会在memcpy上发生段错误

MrD*_*Duk 0 c++ memcpy

我试图"打包"一个大的mmap()d文件,如下所示:

//numBytes is based on user input
data = static_cast<char*>(mmap((caddr_t)0, numBytes, PROT_READ, MAP_SHARED, myFile, 0));

int
Sender::Packetize(char* data, int numBytes)
{
    int seqNum = 1;
    int offset = 0;
    size_t totalPacked = 0;
    unsigned int length = sizeof(struct sockaddr_in);

    bool dataRemaining = true;
    while(dataRemaining)
    {
            //MTU = 1460
        size_t payloadSize;
        (numBytes > MTU) ? payloadSize = MTU : payloadSize = numBytes;
        char* payload = (char*)malloc(payloadSize);

        memcpy(payload, data, payloadSize);
        Packet pac = {seqNum, 0, payloadSize, payload}; //Basic struct

        totalPacked += payloadSize;    
        cout << "Packed Bytes: " << payloadSize << endl;
        cout << "Total Packed: " << totalPacked << endl;

        dataMap.insert(pair<int, struct Packet>(seqNum, pac));

        if(numBytes > MTU)
        {
            offset += MTU;
            data = &data[offset];
        }
        else
            dataRemaining = false;

        numBytes -= MTU;
        seqNum++;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用2MB +文件.当我为numBytes(5000)传递相对较小的东西时,一切似乎都在游泳.但是,如果我尝试传递整个文件(2533431),我会在期间获得段错误memcpy().我注意到它似乎是一个大约100KB的问题:

[.. snip ..]
Packed Bytes: 1460
Total Packed: 99280
Packed Bytes: 1460
Total Packed: 100740
Packed Bytes: 1460
Total Packed: 102200
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试去一个较小的块(100740),我得到:

[.. snip ..]
Packed Bytes: 1460
Total Packed: 16060
Packed Bytes: 1460
Total Packed: 17520
Packed Bytes: 1460
Total Packed: 18980
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)

是否有一些我忽略的根本缺陷,导致我的虚拟机在这里发生了段错误?

The*_*ark 6

我相信这段代码是罪魁祸首

        offset += MTU;
        data = &data[offset];
Run Code Online (Sandbox Code Playgroud)

offset从0开始,数据从x开始.

  • 第一次循环,循环偏移现在是1460,data = data + offset = x + 1460
  • 下一轮循环偏移现在是2920,data = data + offset =(x + 1460)+ 2920 = x + 4380
  • 下一次循环偏移现在是4380,data = data + offset =(x + 4380)+ 4380 = x + 8790

因此data增长速度超过预期.这意味着最终你将访问的范围之外data.

我建议删除data = &data[offset];部件,然后data + offset在memcpy中使用.