c++ - 新的没有分配足够的内存?

标签 c++ new-operator memcpy packets

好吧,我直接从网络中取出数据包并从中提取 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/

相关文章:

c++ - 将结构复制(使用赋值)到 union 内的结构导致段错误

c - memcpy 上的段错误

c++ - codeblocks - 使用大地址感知标志编译

c++ - C++ 中的 void function() 和 void ClassName::function() 有什么区别?

c++ - 如果只知道基类,如何传递派生类?

c++ - 线路运算符(operator)新的段错误

c++ - 我如何使用模板来确定合适的参数传递方法?

使用 operator new : What are the methods of detecting and processing allocation errors? 的 C++ 内存分配

java - 如何在Java SE7中实例化Runnable类型?

c++ - 复制到 vector<unsigned char> 中的无类型对象的内容