copie / affectation

copie / affectation - C - Programmation

Marsh Posté le 11-04-2011 à 22:07:26    

Bonjour,
j'aimerais savoir quand doit - on utiliser une fonction de copie mémoire ( memcpy par exple ) au lieu d'une affectation. Je développe une simple appli client serveur en C.
 
Dans mon cas, j'ai une structure data qui contienne des BIGNUM ( grands nombres )

Code :
  1. struct data {
  2. BIGNUM *prime;
  3. BIGNUM *gen;
  4. ...
  5. }


 
Cette structure est "encapsulée" dans une autre structure contenant entre autre un descripteur de socket.
 
Mon but est d'initialiser prime et gen,
 
Est ce que je devrais faire 1) ou 2)  
 
1)

Code :
  1. BIGNUM *nbprem = BN_bin2bn(...);
  2. monData->prime = nbprem;


 
2)

Code :
  1. BIGNUM *nbprem = BN_bin2bn(...);
  2. memcpy(monData->prime, nbprem, BN_num_bytes(nbprem));//En supposant qu' il y ait suffisamment d'espace mémoire alloué pour monData->prime


 
Merci d'avance pour votre aide.

Reply

Marsh Posté le 11-04-2011 à 22:07:26   

Reply

Marsh Posté le 11-04-2011 à 22:27:30    

2) ca plante. Tu fais un memcpy sur un pointeur non initialisé. j'avais pas lu le commentaire :o
 
 
Que fait BN_bin2bn ? Est ce que ca t'alloue un nouveau BIGNUM ou pas ? Car dans le cas 1 , tu recopies juste le pointeur ( en supposant le comportement de BN_bin2bn ) , dans le cas 2, tu dupliques la mémoire. Que devient nbprem dans ce cas ? ( fuite de mémoire ? ).
 
 
Dans certains cas, memcpy est plus rapide qu'une affectation (voir code source), sur des grandes quantités de données et selon l'alignement mémoire.

Message cité 1 fois
Message édité par xilebo le 11-04-2011 à 22:29:48
Reply

Marsh Posté le 11-04-2011 à 22:28:51    

C'est difficile de repondre sans le detail de BN_bin2bn... Mais bon le but est que tu comprennes la difference ...
 
Dans 1), tu supposes que BN_bin2bn te retourne un pointeur vers une zone memoire qui "t'appartient" (cela veut dire que tu as la charge de la liberer en faisant un delete monData->prime)
 
Dans 2), la zone memoire pointe par nbprem ne t'appartient pas (c'est a dire qu'elle pourra etre libere ou ecrase par autre chose), et donc tu copie son contenu vers une zone qui "t'appartient". Note que tu devras toujours liberer monData->prime.


Message édité par mr simon le 11-04-2011 à 22:30:10
Reply

Marsh Posté le 11-04-2011 à 22:29:44    

xilebo a écrit :

2) ca plante. Tu fais un memcpy sur un pointeur non initialisé.


 
C'est pas faux, mais il a dit "//En supposant qu' il y ait suffisamment d'espace mémoire alloué pour monData->prime"

Message cité 1 fois
Message édité par mr simon le 11-04-2011 à 22:30:43
Reply

Marsh Posté le 11-04-2011 à 22:30:21    

mr simon a écrit :


 
C'est pas faux !


 
 
j'avais pas lu le commentaire, j'ai corrigé.

Reply

Marsh Posté le 11-04-2011 à 23:07:28    

la doc concernant Bn_bin2bn( ) est ici ( http://www.openssl.org/docs/crypto/BN_bn2bin.html ) et ce qu'il nous faut, je le réecris ci-dessous :
 
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
 
BN_bin2bn() converts the positive integer in big-endian form of length len at s into a BIGNUM and places it in ret. If ret is NULL, a new BIGNUM is created.  
 
Si j'ai bien compris, Bn_bin2bn() alloue la zone mémoire nécessaire pour créer une nouvelle BIGNUM.
on peut faire une copie d'une structure avec memcpy alors ...!.? je pensais que c'est reservé uniquement pour des données stockées en mémoire de manière contigue ( les string par exemple ).
Sinon, effectivement, il y a quelques fuites de mémoires que je dois réparer.

Reply

Marsh Posté le 11-04-2011 à 23:34:54    

BN_bin2bn va ecrire dans ret si ret n'est pas NULL, sinon il en cree un nouveau.
 
Ce que je ferais:

Code :
  1. monData->prime = BN_bin2bn(...,...,NULL);
  2. if (monData->prime == NULL) {
  3. // gestion erreur
  4. }
  5. /* ... */
  6. BN_free(monData->prime);


 
C'est ce qu'il y a de plus simple a mon avis, tu laisse la libraire se gerer de l'allocation. Si tu souhaites un "comportement plus fin", alors tu peux faire:

Code :
  1. /** Allocation de monData->prime. */
  2. if(BN_bin2bn(...,...,monData->prime) == NULL) {
  3.  /** gestion erreur. */
  4. }


Message édité par mr simon le 11-04-2011 à 23:35:05
Reply

Marsh Posté le 12-04-2011 à 00:00:48    

c'est à dire le cas 1 ou le cas 2 ...?

Reply

Marsh Posté le 12-04-2011 à 00:34:22    

Ben c'est assez clair: à la gestion d'erreur près,
1) Si monData->prime est pas alloué.Tu fais:
monData->prime = BN_bin2bn(...,...,NULL); // allocation avec BN_bin2bn
2) Si monData->prime est alloué, avec suffisamment d'espace mémoire. Tu fais:
BN_bin2bn(..., ..., monData->prime); // réutilisation par BN_bin2bn de l'espace déja alloué
3) Si monData->prime est alloué, mais avec pas suffisamment d'espace mémoire (si ce cas peut arriver, je ne connais pas tes structures de données pour le savoir). Tu fais:
free(monData->prime); // libération de l'espace alloué trop petit
monData->prime = BN_bin2bn(...,...,NULL); // allocation avec BN_bin2bn
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed