Initialisation d'un char*, malloc ou pas ?

Initialisation d'un char*, malloc ou pas ? - C - Programmation

Marsh Posté le 20-10-2004 à 15:25:56    

Quelle solution vous semble la plus adaptée, sachant que les deux semblent fonctionner ?
 

Code :
  1. #include <stdlib.h> // getenv
  2. #include <stdio.h>  // fprintf
  3. #include <string.h> // strncpy
  4. int main( void )
  5. {
  6.   char* file = "/.ngstar/scores";
  7.   /* SOLUTION 1 */
  8.   char* scorefile = getenv( "HOME" );
  9.   int size = strlen( scorefile );
  10.   /* FIN SOLUTION 1 */
  11.   /* SOLUTION 2 */
  12.   char* scorefile;
  13.   int size = ( strlen( getenv( "HOME" ) ) + strlen( file ) ) * sizeof( char );
  14.   scorefile = (char*)malloc( size );
  15.   strncpy( scorefile, getenv( "HOME" ), size );
  16.   /* FIN SOLUTION 2 */
  17.   strncat( scorefile, file, strlen( file ) );
  18.  
  19.   fprintf( stdout, "%i : %s\n", size, scorefile );
  20. }


---------------
Chết rồi ! ✍ ⌥⌘ http://github.com/gwenhael-le-moine/slackbuilds/
Reply

Marsh Posté le 20-10-2004 à 15:25:56   

Reply

Marsh Posté le 20-10-2004 à 15:45:03    

La solution 2, puisque dans la 1 tu écris après la fin de la chaine renvoyée par getenv. Par contre, si c'est pour utiliser strncat comme tu le fais, autant utiliser strcat (par contre c'est bien pour strncpy). Et puis sizeof(char) == 1. Et puis faut pas oublier le '\0' final quand tu malloc scorefile. Et puis si tu stockais le retour de getenv dans un pointeur, ça t'eviterais de l'appeler deux fois.


Message édité par matafan le 20-10-2004 à 15:48:13
Reply

Marsh Posté le 20-10-2004 à 15:47:45    

strncpy( scorefile, getenv( "HOME" ), size );
-->
boom
 
char*)malloc( size );
-->
magnifique ce cast
 
* sizeof( char )
-->
* 1
 
 
char* file = "/.ngstar/scores";
-->
manque un const
 
 
-->manque des free
 
 

Reply

Marsh Posté le 20-10-2004 à 15:54:15    

matafan a écrit :

La solution 2, puisque dans la 1 tu écris après la fin de la chaine renvoyée par getenv. Par contre, si c'est pour utiliser strncat comme tu le fais, autant utiliser strcat (par contre c'est bien pour strncpy). Et puis sizeof(char) == 1. Et puis faut pas oublier le '\0' final quand tu malloc scorefile. Et puis si tu stockais le retour de getenv dans un pointeur, ça t'eviterais de l'appeler deux fois.


Ce qui donne

Code :
  1. #include <stdlib.h> // getenv
  2. #include <stdio.h>  // fprintf
  3. #include <string.h> // strncpy
  4. int main( void )
  5. {
  6.   char* scorefile;
  7.   char* file = "/.ngstar/scores";
  8.   char* home = getenv( "HOME" );
  9.   int size = ( strlen( home ) + strlen( file ) );// * sizeof( char );
  10.   scorefile = (char*)malloc( size + 1 );
  11.   strncpy( scorefile, home, size );
  12.   strcat( scorefile, file );
  13.  
  14.   fprintf( stdout, "%i : %s\n", size, scorefile );
  15.   free( scorefile );
  16. }


---------------
Chết rồi ! ✍ ⌥⌘ http://github.com/gwenhael-le-moine/slackbuilds/
Reply

Marsh Posté le 20-10-2004 à 15:56:31    

Taz a écrit :

strncpy( scorefile, getenv( "HOME" ), size );
-->
boom

 
char*)malloc( size );
-->
magnifique ce cast
 
* sizeof( char )
-->
* 1
 
 
char* file = "/.ngstar/scores";
-->
manque un const
 
 
-->manque des free


 
ok pour le reste, mais pourquoi boom (ça compile et ça marche) ?


---------------
Chết rồi ! ✍ ⌥⌘ http://github.com/gwenhael-le-moine/slackbuilds/
Reply

Marsh Posté le 20-10-2004 à 15:58:26    

parce strncpy ça pue, ça fout pas bien l'\0'

Reply

Marsh Posté le 20-10-2004 à 16:01:29    

on ta aussi dit de pas caster le malloc et size_t ca mange pas de pain

Reply

Marsh Posté le 20-10-2004 à 16:09:56    

Code :
  1. #include <stdlib.h> // getenv
  2. #include <stdio.h>  // fprintf
  3. #include <string.h> // strcpy
  4. int main( void )
  5. {
  6.   char* scorefile;
  7.   const char* file = "/.ngstar/scores";
  8.   char* home = getenv( "HOME" );
  9.   size_t size = ( strlen( home ) + strlen( file ) );// * sizeof( char );
  10.   scorefile = malloc( size + 1 );
  11. //  strncpy( scorefile, home, size );
  12.   strcpy( scorefile, home );
  13.   strcat( scorefile, file );
  14.  
  15.   fprintf( stdout, "%i : %s\n", size, scorefile );
  16.   free( scorefile );
  17. }


 

DESCRIPTION
       The  strcpy() function copies the string pointed to by src
       (including the terminating `\0' character)  to  the  array
       pointed  to by dest.  The strings may not overlap, and the
       destination string dest must be large  enough  to  receive
       the copy.
 
       The  strncpy()  function  is similar, except that not more
       than n bytes of src are copied. [b]Thus, if there is no  null
       byte  among  the first n bytes of src, the result will not
       be null-terminated.
[/b]


Taz > Ta remarque sur strncpy correspond à ce que j'ai mis en gras ?
 
EDIT : pourquoi ne pas caster un malloc ? réponse : http://www.stanford.edu/~blp/writi [...] -cast.html
 
EDIT2 : et sur le strncpy : http://www.stanford.edu/~blp/writings/clc/strncpy.html


Message édité par cycojesus le 20-10-2004 à 16:22:55

---------------
Chết rồi ! ✍ ⌥⌘ http://github.com/gwenhael-le-moine/slackbuilds/
Reply

Marsh Posté le 20-10-2004 à 16:23:43    

je sais psa ce que ca dis ton truc, mais regarde donc le prototype de malloc et tu veras que ca retourne (bien entendu) un void * qui sert de type générique en c, la conversion est implicite

Reply

Marsh Posté le 20-10-2004 à 16:50:00    

cris56 a écrit :

je sais psa ce que ca dis ton truc, mais regarde donc le prototype de malloc et tu veras que ca retourne (bien entendu) un void * qui sert de type générique en c, la conversion est implicite

ça dis, en gros, qu'en C il ne faut pas caster, qu'en C++ il faut caster sachant que le malloc en C++ c'est mal.


---------------
Chết rồi ! ✍ ⌥⌘ http://github.com/gwenhael-le-moine/slackbuilds/
Reply

Marsh Posté le 20-10-2004 à 16:50:00   

Reply

Marsh Posté le 20-10-2004 à 16:53:15    

voila, et en c++ quand on interface avec des modules en c, il me semble qu'il y a extern "C", donc aucune excuse pour utiliser des malloc/free dans du code c++

Reply

Marsh Posté le 20-10-2004 à 16:58:42    

cris56 a écrit :

voila, et en c++ quand on interface avec des modules en c, il me semble qu'il y a extern "C", donc aucune excuse pour utiliser des malloc/free dans du code c++

j'ai mis du temps à le trouver celui-là [:ddr555]  
 

How should malloc()'s return value be used?
 
In general, the return value of malloc() should be used directly in an assignment or initialization. I don't recommend casting its return value:
 
        * The cast is not required in ANSI C.
        * Casting its return value can mask a failure to #include <stdlib.h>, which leads to undefined behavior. As C99 slows becomes more popular, this will become less of an issue, because C99 requires all functions to be declared before they are called.
        * If you cast to the wrong type by accident, odd failures can result. This is especially true if <stdlib.h> is not #included, as above, but alignment can still cause trouble on particularly odd systems.
 
Some people do disagree, often because such casts are required in C++. But good C++ code should generally avoid malloc() entirely, using C++'s new instead. Most of the time, it doesn't make sense to compile code as both C and C++, outside of specialized circumstances such as those described by P.J. Plauger in article 9sFIb.9066$nK2.4505@nwrddc01.gnilink.net.


 
Quelques trucs en C très pratique ;)


Message édité par cycojesus le 20-10-2004 à 17:02:13

---------------
Chết rồi ! ✍ ⌥⌘ http://github.com/gwenhael-le-moine/slackbuilds/
Reply

Marsh Posté le 20-10-2004 à 17:02:51    

oui, en c99 ya plus de déclarations implicites

Reply

Marsh Posté le 20-10-2004 à 17:06:01    


 
cherches faq + c sur google pages francophones et tu trouveras la meme chose en francais et en plus complet (except les liens *.developpez.com)

Reply

Sujets relatifs:

Leave a Replay

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