2009-03-07 7 views
2

En C, une fonction peut-elle exposer la mémoire qu'elle "gérait" à un niveau inférieur en lecture seule à ceux qui appellent cette fonction (en exposant son adresse). return * const n'est pas efficace, mais je me demandais si je donnais sur une tique de programmation?Expose la mémoire en lecture seule

Merci.

const uint8_t * get_value(int index) 
{ 
static uint8_t data[2] = {0, 0}; 
return (const uint8_t *)&data[index]; 
} 

int main(void) 
{ 
uint8_t * value; 
value = get_value(1); 

*value += 1; 
return 0; 
} 

@j_random_hacker suggéré un bon compromis à ma question qui donne cette barrière supplémentaire Je cherche à empêcher une mauvaise utilisation occasionnelle de ces données.

typedef struct 
{ 
    const uint8_t * value; 
    const uint8_t size; 

} readonly_t; 

readonly_t get_value(int index, int size) 
{ 
    static uint8_t data[2] = {0, 0}; 
    uint8_t rsize; 

    /* ... validate index, size params */ 

    readonly_t r = { &data[index], rsize }; 
    return r; 
} 
+0

Je ne sais pas pourquoi c'est un wiki communautaire. – TheTXI

+0

Mon erreur. Quelques clics ici et là un peu pour rapidement, puis soumettre - mais ne peut pas annuler. – Oliver

Répondre

6

Il est C! Vous ne pouvez pas :) Il y a toujours un moyen de contourner cela. Faites-le simplement const et espérez que quelqu'un ne le changera pas.

Si vous hébergez un complément ou quelque chose, vous devez l'exécuter dans un processus séparé pour limiter son accès à la mémoire.

+0

Réponse sélectionnée, car vous avez techniquement raison - Je ne peux pas obtenir de véritable fonctionnalité en lecture seule dans ce scénario. Merci pour votre contribution – Oliver

1
+0

granularité dépendant de la plate-forme et d'allocation> = 4 Ko. Mais si ce n'est pas un problème ... :) – peterchen

+0

Ne fonctionne pas sur la plate-forme MS, loin de là. En utilisant un système d'exploitation OSEK et vanilla C, pas de bibliothèques standard, etc. – Oliver

+0

Ouais, son genre de réponse skeezy, je suis d'accord. Mais j'ai pensé que d'autres personnes feraient remarquer son impossibilité dans C. Bien sûr, les appelants peuvent toujours utiliser VirtualProtect() pour changer le statut. La meilleure chose à faire est de renvoyer une poignée de quelque sorte et de la mapper à la structure de données opaque en interne. –

1

Ne pas retourner un pointeur, retourner la pointe à la valeur de objet comme dans:

uint8_t get_value(int index) 
{ 
    static uint8_t data[2] = {0, 0}; 
    return data[index]; 
} 
+0

Je voudrais mais ce pourrait être n octets de longueur, par exemple une structure – Oliver

+0

Ensuite, ce que vous avez déjà est le mieux que vous pourriez avec cette langue. – dirkgently

+0

Si n est corrigé, vous pouvez envelopper le tableau dans une structure et renvoyer cette valeur. C permet de traiter les structures comme des valeurs de première classe (elles peuvent être affectées de =, passées et renvoyées à partir de fonctions) mais pas de tableaux pour une raison quelconque. –

0

Protection de la mémoire est pas une construction linguistique dans « C, il est quelque chose à voir avec le matériel. Par exemple, si la mémoire pointée par le pointeur est dans une zone ROM ou quelque chose, l'écriture n'est pas possible. Et à l'inverse, nous pouvons même faire la partie de ReadOnly au niveau matériel, alors vous pouvez vous attendre à une exception de mémoire.

Questions connexes