簡體   English   中英

設置指向結構的指針

[英]Setting pointers to structs

我有以下結構:

struct Datastore_T
{
 Partition_Datastores_T  cmtDatastores; // bytes 0 to 499
 Partition_Datastores_T  cdhDatastores; // bytes 500 to 999
 Partition_Datastores_T  gncDatastores; // bytes 1000 to 1499
 Partition_Datastores_T  inpDatastores; // bytes 1500 1999
 Partition_Datastores_T  outDatastores; // bytes 2000 to 2499
 Partition_Datastores_T  tmlDatastores; // bytes 2500 to 2999
 Partition_Datastores_T  sm_Datastores; // bytes 3000 to 3499
};

我想設置一個 char* 以指向這種類型的結構,如下所示:

struct Datastore_T datastores;

// Elided: datastores is initialized with data here

char* DatastoreStartAddr = (char*)&datastores;
memset(DatastoreStartAddr, 0, 3500);

我遇到的問題是,當 DatastoreStartAddr 應該指向已用數據初始化的結構時,它的值始終為零。

我究竟做錯了什么?

編輯:我的意思是零是結構中的“值”即使在我初始化結構之后都是零。 地址不是零,而是結構中的值為零。

編輯:我想我問的問題錯了。 讓我們重新開始。 如果我有一個用數據初始化的結構,並且另一個對象維護一個字段成員,該成員是指向該結構的指針,如果直接更改該結構:

struct Datastore_T datastores;
char* DatastoreStartAddr = (char*)&datastores;

datastores.cmtDatastores.u16Region[0] = Scheduler.GetMinorFrameCount(); // byte 40,41
datastores.cmtDatastores.u16Region[1] = Scheduler.GetMajorFrameCount(); // byte 42,43

我不應該能夠使用 DatastoreStartAddr 指針訪問這些更改嗎?

編輯:以下代碼嘗試讀取數據存儲中的數據集,但使用指向結構的指針:

            CMT_UINT8_Tdef PayLoadBuffer[1500]= {NULL};
            int TDIS = 0;
            int DIS = 0;
            int DSA = 0;

            //copy DataStore info using address and size offsets
            if ((PayLoadBuffer + TDIS + DIS) < IndvDEMMax)
            {
               memcpy((PayLoadBuffer + TDIS), Datastores+DSA, DIS);
               TDIS += DIS;
            }

memcpy((PayLoadBuffer + TDIS), Datastores+DSA, DIS)行中,Datastores 應指向結構並嘗試訪問該結構中的偏移量。 但由於該值始終為零,因此它會在 PayLoadBuffer 中復制零。

我不知道為什么你得到的地址為零,但我猜你沒有顯示的代碼與它有關。 其他幾點:

  • 考慮在結構中使用Partition_Datastores_T數組
  • 不要對結構大小使用幻數,你需要sizeof(Datastore_T )
  • 不需要中間char*

編輯:鮑比,回答您的補充問題 - 是的,您應該能夠通過指針訪問它,但不能通過char *訪問它(無需跳過一些箍)。 你要:

struct Datastore_T datastores;
struct Datastore_T * DatastoreStartAddr = &datastores;

當您使用該指針時:

DatastoreStartAddr->cmtDatastores.u16Region[0] = Scheduler.GetMinorFrameCount(); 

請注意->運算符的使用。

我剛剛測試了你的代碼,它不是零。 嘗試發布更大的作品

您以錯誤的順序進行操作 - 應該是這樣的

struct Datastore_T datastores;
char* DatastoreStartAddr = (char*)&datastores;
memset(DatastoreStartAddr, 0, sizeof(Datastore_T));

// Elided: datastores is initialized with data here

現在數據存儲仍然是初始化的。 就像其他人說的你可能想要這個

struct Datastore_T * DatastoreStartAddr = datastores;
memset((void *)DatastoreStartAddr, 0, sizeof(Datastore_T));

我假設您沒有顯示的代碼是正確的。 將它展示給我們進行審查可能是明智的。 很可能,我下面所說的根本不是問題。

由於演員陣容,您可能在這里遇到了別名問題。 如果您設置了激進的編譯器優化標志(例如 gcc 上的-fno-strict-aliasing ),編譯器會假設這兩個指針永遠不會指向同一事物,因為它們具有不同的類型。 然后,這兩種表示中的一種或兩種可能會緩存在不同的 CPU 寄存器中,因此對一個表示的更新永遠不會反映在另一個中。

再次,這是一個長鏡頭。 考慮到您的struct的大小(當我開始回答您的重復問題時我沒有看到),它不太可能駐留在主內存中的其他任何地方。 但是您可以嘗試拒絕編譯器優化,看看它是否有所作為。

在什么時候您的結構值為零? 如果它在 cast 和memset() ,則問題出在您的初始化上。 如果是在 cast 和memset() ,則結構中的值為零,因為memset()用 0 覆蓋了您初始化它的值。 memset()之后, datastores的值也應該為零。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM