-1

I need to scan an array and figure out when "healthy" values end and when garbage values are about to start. How i can do that? That's the code:

int main (int argc,char *argv[]){
  

char x[2000000];
x[0] = 'c';
x[1] = 'i';
x[2] = 'a';


for (int i = 0;i<sizeof(x)/sizeof(x[0]);i++){
    // Here an if that print only healty char
  }

}
  • 2
    How would you as a human recognise a garbage value? If you can specify that, an answer could show how to implement that. – Yunnosch Jul 24 '21 at 07:22
  • 2
    There is no way to distinguish a character that is meaningful from a character that is, or might be, garbage. A `char` that has no meaning (i.e. is garbage) can be indistinguishable from a `char` value that represents a meaningful character. Of course, you can test is a `char` value is a letter or number or something. But that isn't to distinguish garbage. – Stephen C Jul 24 '21 at 07:23
  • 2
    Initialize the whole array with zeroes (`char x[2000000] = {0};`) and assume every `'\0'` is garbage **or the string terminator**. – pmg Jul 24 '21 at 07:23
  • @pmg That is probably an answer to the question which OP meant to ask. – Yunnosch Jul 24 '21 at 07:24
  • You should be aware that reading uninitialized ("unhealthy") values constitutes undefined behavior, which means your program could malfunction in unpredictable ways if you do so. – user4815162342 Jul 24 '21 at 07:29
  • Any value that you did not assign, is a garbage value. So all variables must be `initialized` – Daoist Paul Jul 24 '21 at 07:34
  • @user4815162342 Actually, if you define your array as `char x[2000000];`, then reading those values is a perfectly defined behavior - you just read the value at a very well defined address, nothing undefined about that. – Captain Trojan Jul 24 '21 at 07:40
  • 1
    @CaptainTrojan It's a bit more complex than that, more e.g. [here](https://stackoverflow.com/questions/11962457/why-is-using-an-uninitialized-variable-undefined-behavior). You're probably right that for a trap-free type like `char` behavior is not automatically undefined, but you get an "unspecified" value which doesn't even have to be the same value when you read it twice. The compiler is not obliged to "read from address" if the value is uninitialized. You can end up in a situation where `if (x[100]) foo();` followed by `if (!x[100]) bar();` invokes _both_ `foo()` and `bar()`. – user4815162342 Jul 24 '21 at 07:56
  • Considering your almost 2 MiB large array, your program will not run on Windows which only has a single MiB as default stack. Don't use large arrays as local variables (and don't use global variables at all, not even for such arrays). – Some programmer dude Jul 24 '21 at 14:29

2 Answers2

3

figure out when "healthy" values end and when garbage values are about to start. How i can do that?

You can't.

In C there is no way to tell whether a variable has been assigned a value. It's your responsibility to make sure that you don't use variables before they have a well defined value (note: there are exceptions to this rule but they are irrelevant here).

In your case x[3], x[4], ... etc. are never assigned values so they shouldn't be used. But again - there is no way to find out at run-time.

The classic work around is to use a sentinel value (see https://en.wikipedia.org/wiki/Sentinel_value).

In C this is well known from string handling where the null character '\0' is used to signal: end-of-string

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
0

One way to do it is to have another array "mapping" to each value of the other array. Once you write a value to the first array, the value of the second in the same position turns to 1 (they should all be default 0).

Then, when checking for garbage values, if the position of the corresponding array is 0, then it's a garbage value.

See if this code helps:

#include<stdio.h>

#define ARRAY_SIZE 200

void insertIntoArray(size_t pos,char *x,int *xPoint,char value);

int main(void){
  char x[ARRAY_SIZE];
  int xPoint[ARRAY_SIZE];

  //initialize pointer array
  for(size_t i=0;i<ARRAY_SIZE;i++){
    xPoint[i]=0;
  }

  //insert some values
  insertIntoArray(0,x,xPoint,'A');
  insertIntoArray(1,x,xPoint,'B');
  insertIntoArray(2,x,xPoint,'C');
  insertIntoArray(6,x,xPoint,'D');
  insertIntoArray(9,x,xPoint,'E');

  //check for garbage values
  for(size_t i=0;i<ARRAY_SIZE;i++){
    if(xPoint[i]==0){
      printf("Garbage Value!\n");
    }
    else{
      printf("%c\n",x[i]);
    }
  }

  return 0;
}

void insertIntoArray(size_t pos,char *x,int *xPoint,char value){
  x[pos]=value;
  xPoint[pos]=1;
}

Here, I create two arrays with the same size. The second is just to map for the first one, hence I initialize all its values to 0.

Then, I created a function that inserts a value to the first array, turning the corresponding value of the second to 1.

Finally, I loop through the array; if the second's corresponding value is 0, the value of the first array is a garbage value; if it's 1, the value is legit.

The output is the following:

A
B
C
Garbage Value!
Garbage Value!
Garbage Value!
D
Garbage Value!
Garbage Value!
E
Garbage Value!
Garbage Value!
Garbage Value!
Garbage Value!
Garbage Value!
...