typedef char * string_t;
Here, I follow the common convention of ending typedef names with "_t". C typedef names are synonyms for explicit C type specifications and help make your C programs more readable. (In Chapter 4, I describe a more comprehensive way to deal with strings in C. In this chapter, I cover only conventional C string-handling. You can combine suggestions from both chapters to build your own complete string facility.)
Figure 6.5 Creating a Dangling Pointer
char* month_name( const int month ) { /* | Return month name */ char names[10][12] = { "January", ... "December" }; return names[ month - 1 ]; }
Figure 6.6 uses string_t to declare parameters for the function new_string. (A similar function, strdup, is available in Microsoft C but not in ANSI C.) With this function, it's easy to write a correct version of month_name, as shown in Figure 6.7. Like Figure 6.5's incorrect version, the corrected version returns a character pointer. However, the pointer returned by the corrected version points to memory that remains allocated and that contains the desired month name.
Figure 6.6 new_string Function
string_t function new_string( const string_t val ) { /* | Allocate and load storage for string val | | Return pointer or NULL, if error */ string_t p; if ( val == NULL ) { printf( "Invalid NULL value pointer\n" ); return NULL; } p = (string_t) malloc( strlen( val ) + 1 ); if ( p == NULL ) { printf( "No memory for %s\n", val ); return NULL; } else { strcpy( p, val ); return p; } }
Figure 6.7 Corrected month_name Function
char * month_name( const int month ) { /* | Return month name */ char names[10][12] = { "January", ... "December" }; return new_string( names[ month - 1 ] ); }
updated