繁体   English   中英

memcpy极其意外的行为

[英]memcpy extremely unexpected behavior

我正在使用memcpy在磁盘上写入的数组中复制信息。 我要存储一个256字节的char *(名称数组)*3个长数字一个短数字 我以为它可以正常工作,直到我尝试了,但没有成功。 将信息保存到磁盘时,一切似乎都可以正常工作。 但是,当尝试读取信息时,memcpy只会发生故障,将变量直接保留在名称数组之后为0,并且当我的程序需要它来加载其他内容时,我会遇到段错误。

起初,我认为信息在写入磁盘或从磁盘加载时可能已经损坏,但是我发现保存或加载过程没有任何大问题,所以接下来要做的是打印出每个数组上的单个字节(使用Qt的qDebug),看看是否可以发现任何错误。

不用说,它不能按计划进行,因为qDebug仅打印非空字符,并且“名称数组”有很多这样的字符,但它却出奇的令人惊讶:从某种意义上说,它使memcpy工作并且不工作它会成功复制第一个长号,但是会损坏第二个长号。 问题是,整个事情几乎没有关系!

            char* block = new char[FreeBlock::TablaMTD_v]; //3958 bytes long
            fRead.seekg(toLoad, ios::beg); //toLoad being an unsigned long file pointer, fRead being a working ifstream
            fRead.read(block, FreeBlock::TablaMTD_v); //reading all 3958 bytes to block
            fRead.close();
            short bsize = 0, pos = 0;
            memcpy(&bsize, block, 2);
            pos+=2;
            for(short i = 0; i < bsize; i++){
                char* tname = new char[257];
                unsigned long ptrmtd = 0, ptrdt = 0, ptrind = 0;
                unsigned short indmtd = 0;
                memcpy(tname, &block[pos], 256);
                tname[256] = 0;
                pos+=256;
                memcpy(&ptrmtd, &block[pos], 8); //without qdebug loop, stays at 0. otherwise, has correct value
                pos+=8;
                memcpy(&ptrdt, &block[pos], 8); //with qdebug loop, stays at 0. otherwise, has correct value
                pos+=8;
                memcpy(&ptrind, &block[pos], 8);
                pos+=8;
                memcpy(&indmtd, &block[pos], 2);
                pos+=2;
                for(int i = 0; i < FreeBlock::TablaMTD_v; i++){
                    qDebug()<<block[i]; //miracle solution, somehow
                }
                CampoMTDB* cmtd = nextCampoMTDB(ptrmtd, true); //based on ptrmtd, which if 0, returns null pointer
                unsigned long nextcmtdb = cmtd->next; //seg fault due to null pointer

因为那是我唯一添加的for循环,并且对其进行注释/取消注释实际上会改变整个过程的结果,所以我实在感到困惑。 排序为我在“意外行为”方面创下了新记录。

考虑到我是C ++的新手,直到最近我听说我在这里使用的随机危险实践显然不应该使用,我仍然不知道如何或为什么在之后添加随机for循环memcpy操作将对这些操作产生任何影响,或者为什么memcpy首先无法正常工作。

另请注意,保存文件后,我没有再触摸它,它完全没有改变,但是读取文件的输出却改变了。

以防万一,我正在Qt 5.3,x64 Windows 7中使用VC2013

由于您在Windows 7下使用VC2013,因此unsigned long的大小为4个字节(而不是8个字节)。

在任何情况下,为了您自己的安全,都应使用sizeof而不是那些常数8和2。

更改此:

memcpy(&ptrmtd, &block[pos], 8);
pos+=8;
memcpy(&ptrdt, &block[pos], 8);
pos+=8;
memcpy(&ptrind, &block[pos], 8);
pos+=8;
memcpy(&indmtd, &block[pos], 2);
pos+=2;

对此:

memcpy(&ptrmtd, &block[pos], sizeof(ptrmtd));
pos+=sizeof(ptrmtd);
memcpy(&ptrdt, &block[pos], sizeof(ptrdt));
pos+=sizeof(ptrdt);
memcpy(&ptrind, &block[pos], sizeof(ptrind));
pos+=sizeof(ptrind);
memcpy(&indmtd, &block[pos], sizeof(indmtd));
pos+=sizeof(indmtd);

由于系统上的sizeof(unsigned long) == 4 ,因此memcpy(&ptrmtd, &block[pos], 8); 可以修改不是您的内存。 这是非常危险的,所以永远不要这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM