我正在尝试“打包”一个大的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;
}
我正在使用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)
但是,如果我尝试去一个较小的块(100740
),我会得到:
[.. snip ..]
Packed Bytes: 1460
Total Packed: 16060
Packed Bytes: 1460
Total Packed: 17520
Packed Bytes: 1460
Total Packed: 18980
Segmentation fault (core dumped)
是否存在一些我忽略的根本缺陷,导致我的虚拟机出现错误?
答案 0 :(得分:6)
我相信这段代码是罪魁祸首
offset += MTU;
data = &data[offset];
偏移量从0开始,数据从x开始。
所以data
的增长速度超过预期。这意味着最终您将访问data
。
我建议删除data = &data[offset];
部分,并在memcpy中使用data + offset
。
答案 1 :(得分:1)
你正在泄露payload
记忆。不free
内存导致问题。
<强>问题强>
在所有内存耗尽后,malloc返回NULL
。
您应该始终检查malloc的返回值以确保分配成功。
如果您尝试将内容复制到NULL内存中,则会出现段错误。
<强>解决方案强>
在适当的位置使用free
来释放内存。
我建议在进入循环之前分配MTU大小的内存并在循环之后返回它。如果MTU是编译时常量,则可以更好地使用静态大小的数组,而不是动态分配它。
因为您使用的是C ++而不是char* payload = (char*)malloc(payloadSize);
,所以您可以从某个STL容器中获取内存以自动释放内存。
vector<unsigned char> buf(size);
payload = &buf[0];
当buf超出范围时,你的记忆将被释放。