2010-03-30 7 views
1

je la struct suivante:pointeurs de réglage à 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 
}; 

Je veux définir un char * pour pointer vers un struct de ce type comme ceci:

struct Datastore_T datastores; 

// Elided: datastores is initialized with data here 

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

Le problème que j'ai est DatastoreStartAddr a toujours la valeur zéro lorsqu'il doit pointer vers la structure qui a été initialisée avec des données.

Qu'est-ce que je fais mal?

Editer: Ce que je veux dire par zéro, c'est que les "valeurs" dans la structure sont toutes des zéros même après avoir initialisé la structure. L'adresse n'est pas nulle, ce sont les valeurs dans la structure qui sont nulles.

Edit: Je pense que je pose la mauvaise question. Recommençons. Si j'ai un struct qui est initialisé avec des données, et un autre objet tient à jour un membre de champ qui est un pointeur sur cette struct, si le struct change directement:

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 

je ne devrais pas être en mesure d'accéder à ces changements utilisant le pointeur DatastoreStartAddr?

EDIT: Le code suivant tente de lire l'ensemble des données dans datastores, mais en utilisant le pointeur vers la struct:

  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; 
      } 

Dans la ligne memcpy((PayLoadBuffer + TDIS), Datastores+DSA, DIS), Datastores devrait pointer vers la structure et les tentatives d'accéder à un compenser dans cette structure. Mais comme la valeur est toujours zéro, il copie zéro dans le PayLoadBuffer.

+5

Vous ne pouvez pas juste 'memset (& datastores, 0, sizeof (struct Datastore_T));' ou quelque chose? –

+2

Puisqu'il s'agit de C++, vous pouvez utiliser DataStore_T datastores = DataStore_T(); '(initialisation de la valeur pour le gain!) –

+0

@Bobby Si c'est votre code d'initialisation qui est actuellement en panne, POURQUOI NE L'AVEZ-VOUS PAS MONTRÉ? Et qu'est-ce que le truc de memset() a à voir avec ça? Vous vous rendez compte que l'appel de memset mettra zéro la structure, je suppose? –

Répondre

4

Je ne sais pas pourquoi vous obtenez une adresse de zéro, mais je suppose que le code que vous ne montrez pas a quelque chose à voir avec cela. Quelques autres points:

  • envisager d'utiliser un tableau de Partition_Datastores_T dans votre struct
  • ne pas utiliser les nombres magiques pour les tailles struct, vous voulez sizeof (Datastore_T)
  • il n'y a pas besoin de l'omble chevalier intermédiaire *

Edit: Bobby, pour répondre à votre question supplémentaire - oui, vous devriez être en mesure d'y accéder par un pointeur, mais pas par un char * (sans sauter à travers quelques cerceaux). Vous voulez:

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

et lorsque vous utilisez ce pointeur:

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

S'il vous plaît noter l'utilisation de l'opérateur ->.

+0

Un tel transtypage explicite en char * sera nécessaire si vous voulez utiliser l'arithmétique du pointeur avec un alignement de 1 octet. Je ne suis pas non plus d'accord avec votre «utilisation d'un tableau» - les noms des symboles sont là pour faciliter l'identification/la signification de la variable. Vous devez supprimer la signification des préfixes de symboles "sm_" "tml" et ainsi de suite si vous devez utiliser un tableau dans lequel vous devez adresser les valeurs par index et non par nom. – Robert

+1

@Robert La distribution n'est pas nécessaire pour memset(), ce qui est ce qu'il fait. Et je n'ai pas dit "utiliser un tableau", j'ai dit qu'il devrait envisager de le faire.Sans savoir comment il utilise la structure, il est difficile de dire si les sous-structures nommées ont une signification ou non. –

+0

@Neil: si le code ci-dessus rend l'intégralité du programme, vous auriez tout à fait raison: memset prend un pointeur générique void * comme premier paramètre et aucun cast explicite n'est nécessaire. Mais comme la majorité du code affiché sur SO n'est que des fragments, il est plus probable que le cast vers un char-pointeur ait une signification (par exemple pour accélérer le codage suivant l'arithmétique des pointeurs). – Robert

0

Je viens de tester votre code et ce n'est pas zéro. Essayez de poster un plus gros morceau

0

Vous le faites dans le mauvais ordre - devrait être comme ça

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

// Elided: datastores is initialized with data here 

est encore maintenant des magasins de données initialisé.Et comme tout le monde dit que vous pourriez vouloir cela à la place

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

Je suppose que le code que vous ne montrez pas est correct. Il serait peut-être sage de nous le montrer pour examen. Probablement, ce que je dis ci-dessous n'est pas du tout le problème. En raison de la distribution, pourrait être que vous avez aliasing questions ici. Si vous avez défini des indicateurs d'optimisation de compilateur agressifs (par exemple -fno-strict-aliasing sur gcc), le compilateur suppose que ces deux pointeurs ne peuvent jamais faire référence à la même chose, car ils ont des types différents. Ensuite, l'une ou l'autre ou les deux représentations pourraient être mises en cache dans des registres de CPU différents, de sorte que les mises à jour de l'une ne seraient jamais reflétées dans l'autre.

Encore une fois, ceci est un long shot. Compte tenu de la taille de votre struct (je ne l'ai pas vu quand j'ai commencé à répondre à votre question en double), il est très peu probable qu'il réside ailleurs que dans la mémoire principale. Mais vous pouvez essayer de désactiver les optimisations du compilateur et voir si cela fait une différence.

0

À quel point les valeurs de votre structure sont-elles nulles? Si c'est avant la distribution et memset(), le problème est avec votre initialisation. Si c'est après la distribution et memset(), alors les valeurs dans votre structure sont nulles car memset() a écrasé avec 0 les valeurs que vous l'avez initialisé. Les valeurs de datastores doivent également être égales à zéro après memset().