Advertisement
spikeysnack

vla_test.c

Jul 4th, 2017
380
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.39 KB | None | 0 0
  1. /* vla_test.c */
  2. /* compile
  3.    clang -std=gnu99 -ggdb3 -o vla_test vla_test.c
  4. */
  5. /* run
  6.    ./vla_test n
  7.         where  n =  {1, 2, 3, 4, 5}
  8. */
  9.  
  10. /** A test. 5 similar functions,
  11.     some of them correct, some not.
  12.  
  13.     Which ones are good?
  14.     which are bad?
  15.     which are dangerous?
  16. */
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <ctype.h>
  21.  
  22. typedef void (*string_function)(char* s);
  23.  
  24. void string_func1(char* s);
  25. void string_func2(char* s);
  26. void string_func3(char* s);
  27. void string_func4(char* s);
  28. void string_func5(char* s);
  29.  
  30. #define SIZE 1000
  31. #define CHARSIZE  sizeof(char)
  32. #define PSIZE     sizeof(char*)
  33. #define DEFAULTSTRING  "DEFAULTSTRING"
  34.  
  35. int main( int argc, char** argv )
  36. {
  37.   string_function f;
  38.   char teststring[80] ={0};
  39.   int n;
  40.  
  41.   if (argc < 2)
  42.     {
  43.       fprintf(stderr, "usage:\tvla_test <int>  {1-5}\n\n");
  44.       exit(1);
  45.     }
  46.  
  47.   if ( sscanf( argv[1], "%d", &n) != 1)
  48.     {
  49.       fprintf(stderr, "need an integer (1-5)\n");
  50.       exit(1);
  51.     }
  52.  
  53.   if (argc >=3 )
  54.     {
  55.       strncpy(teststring, argv[2], 80);
  56.     }
  57.   else
  58.     strncpy(teststring, DEFAULTSTRING, 80);
  59.  
  60.   /*  Dispatch Tables -- "So Hot Right Now!!" */
  61.   switch(n)
  62.     {
  63.     case 1:
  64.       f = string_func1;
  65.       break;
  66.     case 2:
  67.       f = string_func2;
  68.       break;
  69.     case 3:
  70.       f = string_func3;
  71.       break;
  72.     case 4:
  73.       f = string_func4;
  74.       break;
  75.     case 5:
  76.       f = string_func5;
  77.       break;
  78.     default:
  79.       fprintf(stderr, "need an integer (1-5)\n");
  80.       exit(1);
  81.     }
  82.  
  83.   f(teststring);  /* call it */
  84.  
  85.  } /* main*/
  86.  
  87. /******QUESTION*********/
  88.  
  89. /* This function  compiles without error.
  90.    But is it a correct use of memory management?
  91.    If so, why? If not, why not?
  92. */
  93.  
  94. /* make and print 1000 strings */
  95. void string_func1(char* s)
  96. {
  97.   int i              = 0;
  98.   int len            = 0;
  99.   len = strlen(s) + 1;
  100.  
  101.   /* allocate string pointers */
  102.   char** stringarray = (char**) malloc( SIZE * PSIZE );
  103.  
  104.   for(i = 0; i < SIZE; i++)
  105.     {
  106.       /* allocate string */
  107.       stringarray[i] = (char*) malloc( len * CHARSIZE);
  108.      
  109.       /* set string */
  110.       stringarray[i]  = s;
  111.     }
  112.  
  113.   /* print */
  114.   for(i = 0; i <SIZE;i++)
  115.     fprintf(stdout, "%d: %s " , i, stringarray[i]);
  116.  
  117.   /* cleanup */
  118.   i = SIZE;
  119.   while(i--)
  120.     free( stringarray[i] );
  121.  
  122.   free(stringarray);
  123. } /* string_func1 */
  124.  
  125. /******QUESTION*********/
  126.  
  127. /* This function compiles without error.
  128.    But is it a correct use of memory management?
  129.    If so, why? If not, why not?
  130. */
  131.  
  132. /* make and print 1000 strings */
  133. void string_func2(char* s)
  134. {
  135.   int i            = 0;
  136.   int len          = 0;  
  137.   len = strlen(s) + 1;
  138.  
  139.   /* allocate string pointers */
  140.   char** stringarray = (char**) malloc( SIZE * PSIZE );
  141.  
  142.   /* duplicate strings */
  143.   for(i = 0; i < SIZE; i++)
  144.     stringarray[i] = strndup(s, len);      
  145.    
  146.   /* print strings */
  147.   for(i = 0; i <SIZE;i++)
  148.     fprintf(stdout, "%d: %s " , i, stringarray[i]);
  149.  
  150.   /* cleanup strings */
  151.   i = SIZE;
  152.   while (i--)
  153.     free( stringarray[i] );
  154.  
  155.   free(stringarray);
  156.  
  157. } /* string_func2 */
  158.  
  159.  
  160. /******QUESTION*********/
  161.  
  162. /* This function compiles without error.
  163.    But is it a correct use of memory management?
  164.    If so, why? If not, why not?
  165. */
  166.  
  167. /* make and print 1000 strings */
  168. void string_func3(char* s)
  169. {
  170.   int i                = 0;
  171.   int len              = 0;
  172.  
  173.   len = strlen(s) + 1;
  174.  
  175.   /* allocate string pointers */
  176.   char** stringarray = (char**) malloc( SIZE * PSIZE  );
  177.  
  178.   /* allocate & duplicate strings */
  179.   for(i = 0; i < SIZE; i++)
  180.     {
  181.       stringarray[i] = (char*) malloc(len * CHARSIZE );
  182.  
  183.       stringarray[i] = strndup(s, len);      
  184.     }
  185.  
  186.   /* print strings */
  187.   for(i = 0; i <SIZE; i++)
  188.     fprintf(stdout, "%d: %s " , i, stringarray[i]);
  189.  
  190.   /* cleanup strings */
  191.   i = SIZE;
  192.   while (i--)
  193.     free( stringarray[i] );
  194.  
  195.   free(stringarray);
  196.  
  197. } /* string_func3 */
  198.  
  199.  
  200. /******QUESTION*********/
  201.  
  202. /* This function  compiles without error.
  203.    But is it a correct use of memory management?
  204.    If so, why? If not, why not?
  205. */
  206.  
  207. void string_func4(char* s)
  208. {
  209.  
  210.   int i = 0;
  211.   char* strings[SIZE]    = {0};
  212.   int len       = strlen(s) +1;
  213.   char stringarray[len * SIZE];  
  214.  
  215.   /* initialize to 0 */
  216.   memset(stringarray, 0, (len * SIZE) );
  217.  
  218.   /* assign string pointers */
  219.   for (i=0; i < SIZE; i++)
  220.       strings[i] = (stringarray+(i*len));
  221.  
  222.   /* copy strings */
  223.   for (i=0; i < SIZE; i++)
  224.       strncpy (strings[i], s, len);
  225.  
  226.   /* print strings */
  227.     for (i=0; i < SIZE ; i++)
  228.       fprintf(stdout, "%d: %s " , i, strings[i]);
  229.  
  230.     /* cleanup */
  231.     memset(stringarray, 0, (len * SIZE) );
  232.     memset(strings, 0, SIZE);
  233.  
  234. } /* string_func4 */
  235.  
  236.  
  237. /******QUESTION*********/
  238.  
  239. /* This function  compiles without error.
  240.    But is it a correct use of memory management?
  241.    If so, why? If not, why not?
  242. */
  243.  
  244. void string_func5(char* s)
  245. {
  246.   int i           = 0;
  247.   int len         = 0;
  248.   char* strings[SIZE] = {0};
  249.   len  =  strlen(s) +1;
  250.  
  251.   /* allocate & copy string */
  252.   for (i =0; i < SIZE; i++)
  253.     {
  254.       strings[i] = (char*) malloc( len * CHARSIZE);
  255.       memcpy(strings[i], s, len);
  256.     }
  257.  
  258.   /* print stings */
  259.   for (i =0; i < SIZE; i++)
  260.     fprintf(stdout, "%d: %s " , i, strings[i]);
  261.  
  262.   /*cleanup*/
  263.   i = SIZE;
  264.   while(i--)
  265.     free(strings[i]);
  266. } /* string_func5 */
  267. /*end*/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement