Home > Enterprise >  How is a char array maximum size in C determined?
How is a char array maximum size in C determined?

Time:09-10

Learning C and checking the reference from the GNU reference manual. I don't understand how is the maximum size that can be allocated to a char array defined in an exact way. In my test program when the allocated size for a string array is "small" it works fine but when it is "large" the program start behaving erratically. The compiler throws no errors when it gets compiled but during runtime, it is affecting the correctness of my program that uses strtok(), missing some valid tokens in the result.

Taking as input (considering 5 an arbitrary "small" array size):

>> 5 
>> 19 65 41 65 56

The sum output is 246 so it works well

But taking as input (considering 53 an arbitrary "large" array size):

>> 53
>> 19 65 41 65 56 74 76 71 29 44 45 9 66 37 59 6 71 8 30 29 41 31 96 86 11 14 29 24 17 65 88 23 21 49 31 96 72 39 83 96 96 63 44 72 85 38 5 11 70 36 90 49 76

The sum output is 2247 which is wrong (correct is 2647). This incorrectness holds for any "large" number of array_size

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(){
  /*Array size is the amount of integers that will be introduced later. E.g: 5 (introducting 5 integers next) -> 3 4 5 6 7*/
  /*The numbers are 1 <= n <= 1000 */
  int array_size;  
  scanf("%d", &array_size);
  printf("The array size you introduced is %d\n", array_size);  

  /* Given that the integers introduced can have at most 4 digits and they are separated by a whitespace character, array_size*5 is allocated */
  char sentence[array_size * 5];
  scanf("\n");
  scanf("%[^\n]%*c", sentence);

  char delimiter = ' ';
  char *token;
  token = strtok(sentence, &delimiter);
  int sumResult; 
  printf("The token %d is %s\n", 1, token);   
                     
  while (token != NULL) {                
    sumResult = sumResult   atoi(token);
    token = strtok(NULL, &delimiter);
    printf("The token is %s\n", token);
  }
  
  printf("%d\n", sumResult);
}

CodePudding user response:

There are (at least) three errors in the program:

int sumResult; leaves sumResult uninitialized. It must be initialized to zero, as with int sumResult = 0;.

strtok(sentence, &delimiter) passes the address of a single character to strtok. For the second parameter, strtok expects a pointer to the first character of a string, meaning a sequence of characters terminating by a null character. Change the definition of delimeter to char delimiter[] = " "; and change both strtok calls to strtok(sentence, delimiter);.

printf("The token is %s\n", token); is executed once when token is a null pointer. For %s, printf should be passed a pointer to the first character of a string, not a null pointer. This can be remedied by moving this printf to be the first line in the while loop and deleting the prior printf("The token %d is %s\n", 1, token);.

CodePudding user response:

int sumResult; 

When sumResult is not initialized, it does not have a determined value. In the language of the C standard, is value is indeterminate, meaning that the program may behave as if sumResult has no fixed value at all; it may appear to have different values at different times. Further, in this program, using it without it being initialized results in the entire behavior of the program not being defined by the C standard.

int sumResult = 0; 

In the C language object (variables) have different storage durations.

  1. Variables defined in the function scope have automatic storage duration and are not automatically initialized.
  2. Variables defined outside of any function (file scope) and variables defined in functions but declared as static have static storage duration and are automatically initialized (to zero or equivalent for their type) on program startup.

You can do it much easier:

int main(void)
{
/*Array size is the amount of integers that will be introduced later. E.g: 5 (introducting 5 integers next) -> 3 4 5 6 7*/
/*The numbers are 1 <= n <= 1000 */
    size_t array_size;  
    if(scanf("%zu",&array_size) != 1) {/* error handling */}
    printf("The array size you introduced is %zu\n", array_size);  
    int array[array_size];

    /* Given that the integers introduced can have at most 4 digits and they are separated by a whitespace character, array_size*5 is allocated */
    int sumResult = 0; 

    for(size_t num = 0; num < array_size; num  )
    {
        if(scanf("%d", array   num) != 1 ) {/* error handling */; break;}
        sumResult  = array[num];
    }
    printf("%d\n", sumResult);
}

https://godbolt.org/z/zoWz1cjc7

Your code "repaired"

int main(){
  /*Array size is the amount of integers that will be introduced later. E.g: 5 (introducting 5 integers next) -> 3 4 5 6 7*/
  /*The numbers are 1 <= n <= 1000 */
  int array_size;  
  scanf("%d", &array_size);
  printf("The array size you introduced is %d\n", array_size);  

  /* Given that the integers introduced can have at most 4 digits and they are separated by a whitespace character, array_size*5 is allocated */
  char sentence[array_size * 5];
  scanf("\n");
  scanf("%[^\n]%*c", sentence);

  char delimiter[] = " ";
  char *token;
  token = strtok(sentence, delimiter);
  int sumResult = 0; 
  printf("The token %d is %s\n", atoi(token), token);   
                     
  while (token != NULL) {                
    sumResult = sumResult   atoi(token);
    printf("The token is %s %d\n", token, atoi(token));
    token = strtok(NULL, delimiter);
  }
  
  printf("%d\n", sumResult);
}

https://godbolt.org/z/1qj3acn55

  • Related