2012-03-13 3 views
4

Possible en double:
C: How come an array's address is equal to its value?Utiliser memcpy avec le nom du tableau

I Code a récemment trouvé dans mon projet qui appelle memcpy avec l'adresse du nom du tableau

int a[10]; 
memcpy(&a, &b ,sizeof(a)); 

Etonnamment (pour moi) ça a l'air de marcher. Si je le change en memcpy(a,b,sizeof(a));?

Est-il autorisé par la spécification C++? Quelqu'un peut-il me diriger vers des ressources sur ce comportement? Y a-t-il des pièges?

J'ai aussi vérifié

assert((void*)&a == (void*)a); 

et &a est en effet le même que a (en plus de son type).

J'ai vérifié ce comportement dans VS2005, VS2008 et VS2010.

Répondre

2

Le nom d'un tableau évalue à l'adresse du début du tableau, de sorte que les deux ont une signification identique. Voir How come an array's address is equal to its value in C? (c'est une question C mais la même chose vaut pour C++).

+0

Oui, le message que vous avez lié donne une bonne réponse. – Kirill

1

Comme vous dites, ce n'est pas grave.

Lorsqu'il est passé en paramètre, le nom du tableau se "désintègre" en un pointeur vers son premier élément.

4

&a est l'adresse du tableau; a peut être implicitement converti à l'adresse du premier élément. Les deux ont la même adresse, et donc les deux donneront la même valeur lors de la conversion en void*.

Y a-t-il des pièges?

memcpy n'est pas typé, il est donc assez facile d'écrire du code qui compile mais se comporte mal; Par exemple, si a était un pointeur plutôt qu'un tableau, alors sizeof a compilerait mais donnerait une valeur erronée. C modèles de l 'Typesafe ++ peut protéger contre que:

std::copy(b, std::end(b), a); // will only compile if `b` has a known end. 
1

Oui, l'adresse d'un tableau est le même que l'adresse de son premier élément.
Il n'est donc pas nécessaire de modifier l'appel memcpy. À moins que vous n'ayez peur que la définition du tableau puisse changer en un pointeur plus tard (comme int* a = new int[10];).

Bien sûr, si vous allez apporter des modifications au programme de toute façon, il est préférable de se passer du memcpy entier et d'utiliser le vrai C++ à la place.