[英]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.