1

So I am trying to use a dynamic array for my program and I do not know if I am doing it right. Should I use const int or just an int only?

int size = 1;
    int *num1 = new int [size];
    int *num2 = new int [size]; 

or

const int size = 1;
        int *num1 = new int [size];
        int *num2 = new int [size]; 
4
  • This does not need to be a const. Although the size of the allocated array will not change after allocation. With that said size == 1 is not that useful. I would not use a dynamic array to store a single integer. Commented Mar 5, 2020 at 14:40
  • 4
    I am trying to use a dynamic array for my program Unless this is a learning / academic requirement, my advice is use std::vector instead. Commented Mar 5, 2020 at 14:42
  • Generally, const blocks writing to a variable. Since in your case size is only read from, there is no difference. Commented Mar 5, 2020 at 14:45
  • Since you mentioned that you wanted to do size++ please make it a constant. The size of a dynamic array is fixed at the time of the new. You can't resize it ever. To increase the size of a dynamic array you allocate a new larger array and copy the previous array. If this is not an academic exercise my advice is to avoid this and instead use the proper c++ dynamic array which is std::vector. Modern c++ teaches us to avoid the of new Commented Mar 5, 2020 at 15:17

2 Answers 2

6

If the size is a compile-time constant that you want to create an "array" from, then I suggest std::array, as in

std::array<int, 1> num1;

If the size isn't known at compile-time then use std::vector, as in

std::vector<int> num1(size);

And if you really have to use explicit dynamic allocation then opt for smart pointers like std::unique_ptr, like

auto num1 = std::make_unique<int[]>(size);

As for if the variable size should be const, constexpr, not qualified at all, or if you should possible use the literal value directly when allocating, then it really depends on use-case, value availability, and personal preference.

On another note, for a size you should rather use the size_t type instead of int. Most programmers will immediately understand that when you use size_t the variable is used to store a size. Otherwise if you use int it could be any arbitrary integer value. Furthermore, size_t is an unsigned type, so it doesn't allow negative numbers, which is one less cause of problems.

Sign up to request clarification or add additional context in comments.

Comments

1

I've seen you ask a few questions about this now, so I want to show you the difference between having to resize a dynamic array and using std::vector, which packages all of the features you'd want in a dynamically-sized block of contiguous memory.

The following code is how to increase a dynamic array to hold user input. We don't know how long the user wants to input numbers for, so we have to keep resizing every time they enter a new number.

int number = 0;
std::size_t array_size = 0; // we need to track the size of the thing
int *array = nullptr; // nothing in here yet

std::cout << "Enter a number, non-number to exit: ";
while (std::cin >> number)
{
   // we need to request more memory
   ++array_size;
   int *new_array = new int[array_size];

   // we have to copy the old array to the new array
   // fun note: as pointed out in the comments below, using memcpy on
   // either src or dest == nullptr is undefined behavior. Just goes to
   // show how hard it is to get something like this correct.
   // Don't do this when we have perfectly good STL containers!
   std::memcpy(new_array, array, (array_size - 1) * sizeof(int));

   // delete the old array, if it exists (we can safely call delete on a nullptr)
   delete[] array;

   // assign the new block of memory to array
   array = new_array;

   // add the retrieved element to array
   array[array_size - 1] = number;

   std::cout << "Enter a number, non-number to exit: ";
}
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

// output the array
for (std::size_t i = 0; i < array_size; i++)
{
    std::cout << array[i] << "\n";
}

// all done, delete the memory that was allocated
delete[] array;
array = nullptr; // not strictly required, but can prevent us from accidentally deleting the same block of memory twice, which would be bad

We can do the same thing using std::vector:

int number;
std::vector<int> vec; // this is a vector that holds ints, it tracks its own size and memmory

std::cout << "Enter a number, non-number to exit: ";
while (std::cin >> number)
{
    vec.push_back(number); // all done

    std::cout << "Enter a number, non-number to exit: ";
}
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

for (std::size_t i = 0; i < vec.size(); i++)
{
    std::cout << vec[i] << "\n";
}

// or we can used range-based for loops, which are awesome
for (auto& v : vec)
{
    std::cout << v << "\n";
}

Note that in the std::vector example, I'm outputting the contents of the std::vector twice, just to show that we have an option for iterating through a vector that is not available for an int *. We don't need to keep track of memory. We don't need to new and delete. When the current program scope exits (if this is a function, for example), the destructor of the std::vector is called and cleans up memory for us.

USE VECTORS!!!

5 Comments

Thanks a lot for making effort to do this, I really appreciate it and understand now.
I think this If either dest or src is a null pointer, the behavior is undefined, even if count is zero. in the following link: https://en.cppreference.com/w/cpp/string/byte/memcpy says you have Undefined Behavior on the first iteration with: std::memcpy(new_array, array, (array_size - 1) * sizeof(int));
@drescherjm I definitely do have undefined behavior here you're right. Another point in favor of using an STL container instead of doing this yourself. It's easy to get wrong!!!
There is no reason to use std::memcpy in the example. Just use std::copy which works with all copyable types rather than only trivially copyable ones. I think std::memcpy and others should be avoided where possible, since they are not type-safe.
@walnut thanks - shows how little I use this functionality. I'm just copying (or memcopying? ;D) what I've seen in 30 year old production code when I have to show how not to do things.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.