好吧,我直接从网络中取出数据包并从中提取 TCP 流。
简而言之,这意味着剥离各种 header (例如,eth->IP->TCP->stream data)。
在我最终完成所有 header 后调用的函数中,我遇到了一个奇怪的错误。
/*Meta is a pointer to the IP header, pkt is a pointer to the TCP header*/
virtual const u_char* processPacket(const u_char* pkt, const u_char* meta) {
//Extract IP info from meta.
iphdr* metaHdr = (iphdr*)meta;
//Form TCP header from the current offset, hdr.
const tcphdr* hdr = (const tcphdr*)pkt;
//Do pointer math to figure out the size of the stream data.
u_int32_t len = ntohs(metaHdr->tot_len) - metaHdr->ihl*4 - hdr->doff*4;
if(len > 0)
{
//Store TCP stream data in a queue, mapped to it's IP source.
TCPStream* stream = new TCPStream();
stream->seqNumber = ntohl(hdr->seq);
stream->streamData = new u_char(len);
//memcpy(stream->streamData, offset(pkt), len);
for(u_int32_t i = 0; i < len; i++)
{
printf("k%i-%i",len, i); //Used to figure out when the segfault occurs.
stream->streamData[i] = offset(pkt)[i]; //Offset returns a pointer to the data under the TCP header
}
//streams[metaHdr->saddr].push(stream);
}
return offset(pkt);
};
TCP 流只是一个 u_int32_t
和一个指向数据包数据拷贝的 u_char*
。
所以,当我使用 memcpy 时,它出现了段错误。
显然,要么我的指针无效,要么我弄乱了我的长度。
在此特定数据包的情况下,数据的长度为 1380 字节(由 Wireshark 确认),因此 len 计算正确。
好的,所以我的指针一定是搞砸了(但不是 NULL)。我做了以下实验:
stream->streamData[0] = offset(pkt)[0]; //Works
stream->streamData[0] = offset(pkt)[len]; //Works, odd.
stream->streamData[len] = offset(pkt)[0]; //Fails, scary
stream->streamData[len] = offset(pkt)[len]; //Fails
所以,当我对 streamData(具体索引 1236)取消引用太远时,我会出现段错误! 但是 streamData 被实例化为:
stream->streamData = new u_char(len);
我在 i=0 时开始迭代 streamData,所以我不会跳过一堆数据。
streamData 是 u_char*
而 offset(pkt)
是 u_char*
所以我没有弄乱我的类型。
在成功迭代 3000 多个其他数据包后,这在特定数据包处失败。转储文件是 27 兆,我有 4 GB 的内存,所以我不认为我用完了或任何东西......所以我不得不得出结论,新的没有分配足够的内存,但为什么?
最佳答案
stream->streamData = new u_char(len);
这会分配一个单独的字符,初始化为 len
。
要分配一个数组,使用:
stream->streamData = new u_char[len];
无论你在哪里释放它:
delete [] stream->streamData;
编辑:
stream->streamData[len] = offset(pkt)[0]; //Fails, scary
即使数组分配正确,这也是未定义的行为。要访问的有效索引为 0 到 len
不包含。
关于c++ - 新的没有分配足够的内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1799697/