ZeroMemory est une fonction disponible sur Windows seulement. Le code n’est pas pas portable
Au niveau de l’utilité. ZeroMemory assure éviter les effets indésirables des optimisations du compilateur mais sans préciser lesquelles.
Bref, préfère utiliser memset qui est standard et portable. De plus, tu es sûr de bénéficier des optimisations du compilateur. Sauf si tu fais de l’assembleur spécifiquement sous Windows, où du coup ZeroMemory pourrait t’être utile.
Juste pour préciser, la doc dit le contraire, la fonction ZeroMemory() ne les évite justement pas, c’est son équivalent SecureZeroMemory() qui est censée les éviter.
Concernant les optimisations indésirables, je suppose que c’est typiquement le cas où un tableau est mis à zéro avant d’être désalloué, le plus souvent pour effacer des données sensibles (comme des mots de passe). Dans un tel cas, voyant que le tableau n’est plus employé après sa mise à zéro, les compilateurs modernes ont la fâcheuse tendance à supprimer purement et simplement cette mise à zéro.
Pour contrer cela, on peut soit désactiver les optmisations (il vaut mieux un programme fiable et lent qu’un programme rapide dans certains cas) soit employer un tableau et une fonction dédiée qualifiés avec le mot-clé volatile.
Si l’on se limite uniquement aux systèmes windows, ZeroMemory est supposé être standard et portable. Comme toutes les API Win32 dont on se sert, pour ainsi dire, de moins en moins.
Ce sont les APIs non documentées dont l’utilisation est à proscrire pour les développeurs, car leur interface est sujette à changement d’une version de Windows à une autre. Mais cela n’intéresse que les adeptes de la magie noire.
Pour le reste, rien à ajouter… memset est à privilégier si tu pars sur du code multi-plateformes, bien entendu !
Vu qu’il y a C++ dans le titre (d’ailleurs « C/C++ » c’est moche), je vais donner le point de vue C++ par rapport à memset (rien à rajouter sur ZeroMemory, tout a déjà été dit.)
En C++ on n’utilise pas memset mais std::fill (documentation). Ça a beaucoup d’avantages, comme le fait d’être type safe et d’être plus général que memset, et ça n’a aucun inconvénient dans les cas d’utilisations similaires à memset, le compilateur pouvant implémenter std::fill en tant que memset dans ces cas là.
Je me permet de réagir sur l’article que tu cites. Techniquement, memset() n’a pas à être utilisée (et ne devrait même pas être utilisée) pour initialiser un aggrégat, une initialisation partielle suffit. En effet, chaque élément de l’aggrégat se verra assigner le « zéro » de son type soit 0 pour les entiers, .0 pour les flottants et (void *)0 pour les pointeurs.
Autrement dit, peu importe le nombre et le type d’éléments de ton aggrégat, cette écriture est toujours correcte et fait le café.
1
type_aggregatobj={0};
La nuance c’est que tu ne peux faire ceci qu’à l’initialisation. Toutefois, si cela s’avère nécessaire, il est aussi possible de le réaliser via un appel à memset() (edit pardon, memcpy(), sinon ça marche moins bien) et un littéral aggrégat ou une autre variable (par exemple de classe de stockage statique) précédemment initialisée.
1
memcpy(&obj,&(type_aggregat){0},sizeofobj);
Édit : pour la structure addrinfo prise en exemple.
#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<errno.h>#include<string.h>#include<sys/types.h>intmain(void){intlistenfd=0,connfd=0;structsockaddr_inserv_addr;charsendBuff[1025];intnumrv;listenfd=socket(AF_INET,SOCK_STREAM,0);printf("socket retrieve success\n");memset(&serv_addr,'0',sizeof(serv_addr));memset(sendBuff,'0',sizeof(sendBuff));serv_addr.sin_family=AF_INET;serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);serv_addr.sin_port=htons(5000);bind(listenfd,(structsockaddr*)&serv_addr,sizeof(serv_addr));if(listen(listenfd,10)==-1){printf("Failed to listen\n");return-1;}while(1){connfd=accept(listenfd,(structsockaddr*)NULL,NULL);// accept awaiting requeststrcpy(sendBuff,"Message from server");write(connfd,sendBuff,strlen(sendBuff));close(connfd);sleep(1);}return0;}
Connectez-vous pour pouvoir poster un message.
Connexion
Pas encore membre ?
Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte