一旦位置接近100KB,则在memcpy上执行segfault
segfault on memcpy once location approaches 100KB
我正试图"打包"一个大的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()
期间得到segfault。我注意到它似乎是一个问题,大约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)
是不是有一些我忽略了的根本缺陷,导致我的虚拟机出现故障?
我相信这段代码是的罪魁祸首
offset += MTU;
data = &data[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];
部分,只在memcpy中使用data + offset
。
您正在泄漏payload
内存。未对内存进行free
操作会导致问题。
问题在所有内存耗尽后,malloc返回NULL
。您应该始终检查malloc的返回值,以确保分配成功。如果您试图将内容复制到NULL内存中,则会得到一个segfault。
解决方案在适当的位置使用free
释放内存。我建议在进入循环之前分配内存的MTU大小,并在循环之后返回。如果MTU是编译时间常数,您可以更好地使用静态大小的数组,而不是动态分配它
因为您使用的是C++,而不是char* payload = (char*)malloc(payloadSize);
,所以您可以从一些STL容器中获取内存来自动释放内存。
vector<unsigned char> buf(size);
payload = &buf[0];
当buf超出范围时,您的内存将被释放。
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- C++,系统无法执行指定的程序
- 使用C++中的模板和运算符重载执行矩阵运算
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 执行函数时导致崩溃的变量
- 无论条件是否为true,if总是在c++中执行
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 在C++中对T*类型执行std::move的意外行为
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如何在没有信号的情况下从C++执行QML插槽
- 如何确认我的constexpr表达式实际上已经在编译时执行
- C++17中的并行执行策略
- QML按钮点击功能执行顺序
- 程序在执行程序的其余部分之前退出
- 为什么catch中的代码没有被执行
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 如何从原始数组到std::vector执行memcpy等效操作
- 执行主机端 malloc 和异步主机到设备 memcpy 的规范方法
- 我真的需要扫描内存两次来执行memcmp + memcpy吗?
- 一旦位置接近100KB,则在memcpy上执行segfault