-4
int *arr = new int[3];
arr[0] = 1;
arr[2] = 3;

for (int i = 0; i < arr.size(); i++)
{
    if(arr[i] exists/initialized) // what would be the condition?
        std::cout << arr[i] << " ";
}

I'm trying to print elements from the array that are initialized, and ignore elements that aren't.

So, the above code would print out:

1 -1231409875 3

I want to fix this so that it outputs:

1 3
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
hobo
  • 1
  • 1
  • 1
    You can't do this in C++. Use a `std::vector`. – tkausl Feb 10 '23 at 20:14
  • cant use a vector. My hw is making a std::deque class implementation – hobo Feb 10 '23 at 20:15
  • 2
    You can initialize allocated arrays to zero values like this: `int *arr = new int[3]{};`. But in modern C++ it is very rare when you need to use `new` directly. Usually its better to use `std::array`, `std::vector`, `std::unique_ptr` or `std::shared_ptr`. – sklott Feb 10 '23 at 20:18
  • I assume you can't use std::optional either – drescherjm Feb 10 '23 at 20:19
  • Is there a value that you will never have in your data like INT_MIN / std::numeric_limits::min()? – drescherjm Feb 10 '23 at 20:21
  • It is not possible to write a condition that checks if a variable of a fundamental type like `int` is initialized or not. If it isn't, any attempt to inspect it is an error. You need to come up with your own scheme to track if an element is significant or not, maybe with a sentinel value representing "no value" or using another parallel array. – François Andrieux Feb 10 '23 at 20:22
  • 3
    *Im trying to print elements from array that are initialized and ignoring elements that aren't.* -- Not possible. All values must be initialized to something before you can use them, whether you are reading the value or writing the value. – PaulMcKenzie Feb 10 '23 at 20:22
  • @PaulMcKenzie It sounds like you mean you can't write to a variable that is uninitialized. You can do `int i; i = 42;`. – François Andrieux Feb 10 '23 at 20:25
  • well its a templated class so it can take any data types. I thought this wasnt possible but when i try to print out that array, It outputs this value "-842150451" for the indexes that werent initialized or equal to another value. Also when I did create the array, it was never initialized from the beginning. – hobo Feb 10 '23 at 20:29
  • @hobo -- What if it printed 0 instead of that large negative number? Or something else that looked "ok"? That's the problem with guessing how C++ works -- you would have been fooled. – PaulMcKenzie Feb 10 '23 at 20:30
  • Im suppose to have it print out a asterisk instead, but since since the array is of a templated type, the datatype for the array might not always be an int – hobo Feb 10 '23 at 20:31
  • @hobo -- Whatever your ultimate goal is, you can't get there by doing what you're doing now -- all variables must be initialized. Maybe the goal of your homework is to see if you can formulate a way to figure out "initialized" from "uninitialized". As mentioned, maybe all values "not initialized" are set to INT_MIN, INT_MAX, or some other value? Or again, maybe another auxiliary array that has the valid indices of the primary array? – PaulMcKenzie Feb 10 '23 at 20:35
  • 1
    If you are making a `std::deque` implementation, tracking the initialization state of every single `int` is overkill. You only need to record the first and last initialized `int`. If an `int` is between those two values, it's initialized. If it's not, it's not. – Drew Dormann Feb 10 '23 at 20:37
  • `-842,150,451` is the same as `0xCDCDCDCD` which is a special value from your compiler in debug mode. It means uninitialized heap memory. Related: [https://stackoverflow.com/questions/127386/what-are-the-debug-memory-fill-patterns-in-visual-studio-c-and-windows](https://stackoverflow.com/questions/127386/what-are-the-debug-memory-fill-patterns-in-visual-studio-c-and-windows) – drescherjm Feb 10 '23 at 20:42
  • @hobo *but since since the array is of a templated type, the datatype for the array might not always be an int* -- What if the type being used automatically initialized itself, like `std::string`? Then there would be no such thing as "uninitialized", since `std::string` is always initialized to something by default. So right there, your requirements will not work -- how are you going to check if a `std::string` is uninitialized, when it can never be uninitialized? Looks like you should take the suggestions made in the comments, and the answer given where you use a `bool` array. – PaulMcKenzie Feb 10 '23 at 21:20

1 Answers1

0

You cannot read from uninitilized elements, theirs values is indeterminate and reading them is undefined.

You can use a bool array of same size, initialize all its elements to false and every time you initialize something in the other array you set the corresponding element to true.

 int* arr = new int[3];
 bool* has_value = new bool[3]{};

 arr[0] = 1;
 has_value[0] = true;
 arr[1] = 42;
 has_value[1] = true;

 for (size_t i= 0;i<3; ++i) {
       if (has_value[i]) std::cout << arr[i] << " ";
       else std::cout << "* ";
 }

As mentioned in comments, if you use a contiguous portion of the array starting at the first element, it is sufficient to store the number of already initialized elements.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • 1
    Rather than using parallel arrays, which can be very error-prone if you are not careful, I would use a single array whose element type is a `struct` or `std::pair`. Keep related values and bools together on a per-element basis. – Remy Lebeau Feb 10 '23 at 23:35