簡體   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