-1

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);
}
Chris
  • 26,361
  • 5
  • 21
  • 42
varinme
  • 45
  • 1
  • 5

2 Answers2

2

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);.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
1
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

0___________
  • 60,014
  • 4
  • 34
  • 74
  • Thanks but it doesn't solve it. It has to do with the size of the array not with the initialization of sumArray. It works consistently well for small sizes but breaks when the amount of numbers is large. – varinme Sep 09 '22 at 18:28
  • @varinme see more simple code – 0___________ Sep 09 '22 at 18:29
  • 1
    @varinme: When the value stored in an object is not controlled, because the program has not initialized it, it can be affected by other things, such as the size of some array that is created. So you cannot conclude merely from experiments showing that the program “works consistently well” for small sizes but not for large sizes means the problem is not that `sumResult` is not initialized. – Eric Postpischil Sep 09 '22 at 18:30
  • Thanks for the insight @EricPostpischil . I did edit the code and initialized sumArray to zero but the behavior is still the same that's why I previously commented that :confused – varinme Sep 09 '22 at 18:38
  • @varinme you do not need strtok to read values. – 0___________ Sep 09 '22 at 18:40