Define array, then change its size - c++

I come from a java background and there's something I could do in Java that I need to do in C++, but I'm not sure how to do it.
I need to declare an array, but at the moment I don't know the size. Once I know the size, then I set the size of the array. I java I would just do something like:
int [] array;
then
array = new int[someSize];
How do I do this in C++?

you want to use std::vector in most cases.
std::vector<int> array;
array.resize(someSize);
But if you insist on using new, then you have do to a bit more work than you do in Java.
int *array;
array = new int[someSize];
// then, later when you're done with array
delete [] array;
No c++ runtimes come with garbage collection by default, so the delete[] is required to avoid leaking memory. You can get the best of both worlds using a smart pointer type, but really, just use std::vector.

In C++ you can do:
int *array; // declare a pointer of type int.
array = new int[someSize]; // dynamically allocate memory using new
and once you are done using the memory..de-allocate it using delete as:
delete[]array;

Best way would be for you to use a std::vector. It does all you want and is easy to use and learn. Also, since this is C++, you should use a vector instead of an array. Here is an excellent reason as to why you should use a container class (a vector) instead of an array.
Vectors are dynamic in size and grow as you need them - just what you want.

The exact answer:
char * array = new char[64]; // 64-byte array
// New array
delete[] array;
array = new char[64];
std::vector is a much better choice in most cases, however. It does what you need without the manual delete and new commands.

As others have mentioned, std::vector is generally the way to go. The reason is that vector is very well understood, it's standardized across compilers and platforms, and above all it shields the programmer from the difficulties of manually managing memory. Moreover, vector elements are required to be allocated sequentially (i.e., vector elements A, B, C will appear in continuous memory in the same order as they were pushed into the vector). This should make the vector as cache-friendly as a regular dynamically allocated array.
While the same end result could definitely be accomplished by declaring a pointer to int and manually managing the memory, that would mean extra work:
Every time you need more memory, you must manually allocate it
You must be very careful to delete any previously allocated memory before assigning a new value to the pointer, lest you'll be stuck with huge memory leaks
Unlike std::vector, this approach is not RAII-friendly. Consider the following example:
void function()
{
int* array = new int[32];
char* somethingElse = new char[10];
// Do something useful.... No returns here, just one code path.
delete[] array;
delete[] somethingElse;
}
It looks safe and sound. But it isn't. What if, upon attempting to allocate 10 bytes for "somethingElse", the system runs out of memory? An exception of type std::bad_alloc will be thrown, which will start unwinding the stack looking for an exception handler, skipping the delete statements at the end of the function. You have a memory leak. That is but one of many reasons to avoid manually managing memory in C++. To remedy this (if you really, really want to), the Boost library provides a bunch of nice RAII wrappers, such as scoped_array and scoped_ptr.

use std::array when size is known at compile time otherwise use std::vector
#include <array>
constexpr int someSize = 10;
std::array<int, someSize> array;
or
#include <vector>
std::vector<int> array; //size = 0
array.resize(someSize); //size = someSize

Declare a pointer:
int * array;

Related

Can I pass a pointer to a pointer, allocate memory, then pass it back?

Consider the following code. This works for allocating a single array, but what if you needed to allocate a two dimensional array? How would you go about doing this?
#include <iostream>
void alloc(int **num)
{
*num = new int[5];
*num[0] = 5;
}
int main()
{
int *num;
alloc(&num);
std::cout << num[0] << std::endl;
delete [] num;
}
My goal is to pass **char into the function and have it allocated. Is this possible?
what if you needed to allocate a two dimensional array?
My goal is to pass **char into function and have it allocated.
So, what you want is a pointer to an array of pointers (each to an array)? That is different from an 2D array, although often treated as such for simplicity.
Just like you added an additional layer of indirection when you allocated that single array, you can add a layer of indirection to allocate an array of pointers, and the pointed to arrays of integers.
So, you could write a function like void alloc(int ***num). Yes, this is possible, but not very good design.
But using a pointer for the indirection makes the syntax more complex, and has the risk of a user passing a null pointer to the function. Instead, a better alternative would be to use a reference: void alloc(int **&num).
Since the function allocates something and "returns a pointer", it would make more sense to actually return the pointer: int** alloc(). Much prettier, isn't it? Less indirection is better.
Finally, there is the problem that a user of the function has to know how to delete the allocated memory. Was it allocated with new or new[]? Maybe even malloc? Or does the function perhaps return a pointer to a static object, that must not be deleted? The caller of the function cannot know that unless it is documented separately.
Also, what if one of the allocation fails? There will be an exception, and the earlier allocations will leak.
The C++ way to solve the above 2 problems is to use a RAII container to manage the memory. Since you apparently want to have an array with pointers to arrays, there is a ready made solution in the standard library for you: return a std::vector<std::vector<int>>. If you instead want a proper non-jagged 2D array i.e. a matrix, then you may want to write a custom RAII container for that, possibly using a flat std::vector<int> for the implementation. Note that a third party may already have implemented such container.
Your code looks like C to me. In C++ I would (maybe) use custom types and not do any manual dynamic allocation. For example
typedef std::vector<int> Row;
typedef std::vector<Row> Matrix;
Matrix initMatrix(int nRows,int nCols) {
return Matrix(nRows,Row(nCols));
}
well in that case you dont even need a function but you can just call the constructor (and let array allocate the memory for you).

I need to resize an array of pointers

Lets say i want to resize an array of int pointers, i have a function that looks like this
template<typename T>
static void Resize(T* arr, UINT oldsize, UINT newsize) {
T* ret = new T [newsize];
memcpy(ret, arr, sizeof(arr[0]) * oldsize);
delete[] arr;
arr = ret;
};
The problems begin when i try and resize an array of elements that were created with the "new" keyword (even though the data itself inside the class is POD) because the delete[] triggers their deconstructor which then leaves the new array with pointers to objects that dont exist anymore. So.. even though the objects were created with "new", cant i just use the free command to get rid of the old array? or somehow delete the array without triggering the deconstructor of each member?
Use a std::vector.
EDIT: by popular demand, an explanation of why the OP's code does not work.
The code:
template<typename T>
static void Resize(T* arr, UINT oldsize, UINT newsize) {
T* ret = new T [newsize];
memcpy(ret, arr, sizeof(arr[0]) * oldsize);
delete[] arr;
arr = ret;
};
Here arr is a pointer passed by value. Assigning to arr at the end only updates the local copy of the actual argument. So after this the actual argument, in the calling code, points to an array that has been deleted, whith pretty catastrophic result!
It could be sort of rescued by passing that pointer by reference:
template<typename T>
static void Resize(T*& arr, UINT oldsize, UINT newsize) {
T* ret = new T [newsize];
memcpy(ret, arr, sizeof(arr[0]) * oldsize);
delete[] arr;
arr = ret;
};
But this is still pretty fragile code.
For example, the caller needs to keep track of the array size.
With a std::vector called a, the resize call would instead look like
a.resize( newSize )
and in contrast to the DIY solution, when newSize is larger, those extra elements of the vector are nulled (which is a bit safer than leaving them as indeterminate values).
A std::vector can be indexed just like a raw array. See your C++ textbook about more details of how to use it. If you don't already have a C++ textbook, do get one: for most people it's just an impractical proposition to learn C++ from articles and Q/A on the web.
For what it's worth, what you're trying to do isn't a terribly bad thing, and there are times it makes sense, but it's simply not supported by the interface provided by new and delete (or new[] and delete[]). As others have said, it is supported by malloc, free, and realloc (with the caveat that realloc will copy the pointer values on reallocation, but won't guarantee that the pointers in the new area are initialized to anything useful, like NULL).
So, without further ado, the easiest answer that will work for almost everybody is to use a std::vector<int> instead of trying to manage the memory yourself. The vector has the ability to resize, and when it does it will copy things that need copying. std::vector exists to provide a "resizable array" and manage the memory for you. Actually, if you want a container of pointers, you're best off using either a std::vector<std::unique_ptr<T>>/std::vector<std::shared_ptr<T>> (in C++11) or something from Boost Pointer Container.
For what it's worth, the original STL did not use new[] or delete[] to implement std::vector<T>. Often, the operating system gives far more memory than you ask for. For instance, if I try to malloc 16 bytes, the block I get back may well be 1024 bytes. I can use that to store four 32 bit integers. When I run out of space, I may ask for 32 bytes, and get a different block of 1024 bytes, which I can copy my four integers to. But why go through the trouble of asking for a new block to hold my integers, when the original block was actually large enough to begin with? Unfortunately, new[] and delete[] don't provide a way to say "give me a block that's at least this large, and by the way here's a block that might already be big enough." realloc kind of does. Facebook Folly includes a std::vector-like container that doesn't use new[] or delete[] (note that it doesn't use realloc either, because that usually won't work with containers of objects; instead it uses malloc and the non-standard function malloc_usable_size), and Firefox goes through the trouble to manage memory in a similar manner.
Even so, I would discourage trying to get tricky. std::vector has a lot of satisfied users.
I think that making all elements in array point to NULL before deleting should do the job. But if you can use STL then std::vector would make your life much easier (as Alf suggested :P).

Is memory freed when dynamic array goes out of scope

I am dynamically allocating memory for an array in a function. My question is: once the function finishes running is the memory freed?
code:
void f(){
cv::Mat* arr = new cv::Mat[1];
...
}
No, memory allocated using new is not automatically freed when the pointer goes out of scope.
However, you can (and should) use C++11's unique_ptr, which handles freeing the memory when it goes out of scope:
void f(){
std::unique_ptr<cv::Mat[]> arr(new cv::Mat[1]);
...
}
C++11 also provides shared_ptr for pointers you might want to copy. Modern C++ should strive to use these "smart pointers", as they provide safer memory management with almost no performance hit.
No, it is not. You must free it by calling
delete[] arr;
But you should ask yourself whether it is necessary to allocate dynamically. This would require no explicit memory management:
void f(){
cv::Mat arr[1];
...
}
If you need a dynamically sized array, you could use an std::vector. The vector will internally allocate dynamically, but will take care of de-allocating it's resources:
void f(){
std::vector<cv::Mat> arr(n); // contains n cv::Mat objects
...
}
No. Every call to new needs to be matched up with a call to delete somewhere.
In your case arr iteself is a variable with automatic storage duration. This means that arr itself will be destroyed when it goes out of scope. However the thing that arr points to does not, because that is a variable that does not have autoatic storage duration.
The fact that arr itself has automatic storage duration can be used to your advantage, by wrapping the raw pointer in a class that destroys the stored pointer when the automatic object is destroyed. This object utilizes an idion known as RAII to implement a so-called "smart pointer". Since this is a very common requirement in well-designed applications, the C++ Standard Library provides a number of smart pointer classes which you can use. In C++03, you can use
std::auto_ptr
In C++11 auto_ptr has been deprecated and replaced by several other better smart pointers. Among them:
std::unique_ptr
std::shared_ptr
In general, it is a good idea to use smart pointers instead of raw ("dumb") pointers as you do here.
If what you ultimately need are dynamically-sized arrays, as supported by C99, you should know that C++ does not have direct support for them. Some compilers (notably GCC) do provide support for dynamically sized arrays, but these are compiler-specific language extensions. In order to have something that approximates a dynamically sized array while using only portable, Standards-compliant code, why not use a std::vector?
Edit: Assigning to an array:
In your comments you describe the way in which you assign to this array, which I have taken to mean something like this:
int* arr = new int[5];
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;
If this is the case, you can accomplish the same using vector by calling vector::operator[]. Doing this looks uses very similar syntax to what you've used above. The one real "gotcha" is that since vectors are dyanamically sized, you need to make sure the vector has at least N elements before trying to assign the element at position N-1. This can be accomplished in a number of ways.
You can create the vector with N items from the get-go, in which case each will be value-initialized:
vector<int> arr(5); // creates a vector with 5 elements, all initialized to zero
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;
You can resize the vector after the fact:
vector<int> arr; // creates an empty vector
arr.resize(5); // ensures the vector has exactly 5 elements
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;
Or you can use a variety of algorithms to fill the vector with elements. One such example is fill_n:
vector<int> arr; // creates empty vector
fill_n(back_inserter(arr), 5, 0); // fills the vector with 5 elements, each one has a value of zero
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;
No, of course not.
For every new you need precisely one delete.
For every new[] you need precisely one delete[].
Since you don't have the matching delete[], your program is broken.
(For that reason, the adult way of using C++ is not to use new or pointers at all. Then you don't have those problems.)
No. The array the allocated on the heap, you'll have to delete it before it goes out of scope:
void f() {
cv::Mat * arr = new cv::Mat[1];
// ...
delete [] arr;
}

Where exactly in memory is count of allocated memory thats being used by delete?

int* Array;
Array = new int[10];
delete[] Array;
The delete knows the count of allocated memory. I Googled that it stores it in memory, but it's compiler dependent. Is there anyway to use get this count?
Actually, the heap knows how large each allocation is. However, that's not something that you can access easily, and it is only guaranteed to be greater than or equal to the amount requested. Sometimes more is allocated for the benefit of byte alignment.
As Ben said though, the implementation does know in certain circumstances how many objects are in the array so that their destructors can be called.
There is no standard way to retrieve the number of elements after construction. In fact, for an int array, it is probably NOT stored anywhere. The count is only necessary for arrays of elements with non-trivial destructors, so that delete[] can call the right number of destructors. In your example, there aren't any destructor calls, since int doesn't have a destructor.
There's no way to get the number of elements of a dynamically allocated array after you allocate it.
The one way to rule them all
However, you can store it beforehand:
int* Array;
size_t len = 10;
Array = new int[len];
delete[] Array;
Custom class
If you don't like that, you could create your own class:
class IntArray
{
public:
int* data;
size_t length;
IntArray(size_t);
~IntArray();
};
IntArray::IntArray(size_t len)
{
length = len;
data = new int[len];
}
IntArray::~IntArray()
{
length = 0;
delete data;
data = NULL;
}
std::vector
The method I recommend is to use std::vector:
std::vector<int> Array (10, 0);
You can use it just like a regular array... with extra features:
for(size_t i = 0; i < Array.size(); ++i)
Array[i] = i;
There are likely one or two counts of the number of elements in such an allocation depending upon the type and the implementation that you are using though you can't really access them in the way you probably want.
The first is the accounting information stored by the actual memory manager that you are using (the library that provides malloc). It will store that a record of some size has been allocated in the free store of the system (heap or anonymous memory allocation are both possible with the glibc malloc for example). This space will be at least as large as the data you are trying to store (sizeof(int)*count+delta where delta is the C++ compiler's tracking information I talk about below), but it could also be larger, even significantly so.
The second count is a value kept by the compiler that tells it how to call destructors on all the elements in the array (the whole magic of RAII), but that value is not accessible and could probably even be done without directly storing the information, though that would be unlikely.
As others have said, if you need to track the information on allocation size you probably want to use a vector, you can even use it as an actual array for the purpose of pointer math if need be (see http://www.cplusplus.com/reference/stl/vector/ for more on this).
Who says that there actually is one?
This stuff depends on the implementation and as such is uninteresting for you, me or whoever wants to know it.
C++ generally intentionally doesn't allow you access to that information, because arrays are simple types that do not keep that information associated with them. Ultimately that information must be stored, but the compiler is free to figure out how, where, and when by the C++ standards to allow for optimization in the assembly.
Basically, either store it yourself somewhere, or (better, most of the time), use std::vector.
No, you need to keep track of it yourself if you need to know.
Many people like using a std::vector if it's not a fixed size. std::vector keeps track of the size allocated for you.

C++ deleting a pointer to a pointer

So I have a pointer to an array of pointers. If I delete it like this:
delete [] PointerToPointers;
Will that delete all the pointed to pointers as well? If not, do I have to loop over all of the pointers and delete them as well, or is there an easier way to do it? My google-fu doesn't seem to give me any good answers to this question.
(And yeah, I know I need to use a vector. This is one of those "catch up on C++" type assignments in school.)
Yes you have to loop over the pointers, deleting individually.
Reason: What if other code had pointers to the objects in your array? The C++ compiler doesn't know if that's true or not, so you have to be explicit.
For an "easier way," two suggestions: (1) Make a subroutine for this purpose so at least you won't have to write the code more than once. (2) Use the "smart pointer" design paradigm where you hold an array of objects with reference-counters, then the objects are deleted when the objects are no longer referenced by any code.
I agree with Jason Cohen though we can be a bit clearer on the reason for needing to delete your pointers with the loop. For every "new" or dynamic memory allocation there needs to be a "delete" a memory de-allocation. Some times the "delete" can be hidden, as with smartpointers but it is still there.
int main()
{
int *pI = new int;
int *pArr = new int[10];
so far in the code we have allocated two chunks of dynamic memory. The first is just a general int the second is an array of ints.
delete pI;
delete [] pArr;
these delete statements clear the memory that was allocated by the "new"s
int ppArr = new int *[10];
for( int indx = 0; indx < 10; ++indx )
{
ppArr[indx] = new int;
}
This bit of code is doing both of the previous allocations. First we are creating space for our int in a dynamic array. We then need to loop through and allocate an int for each spot in the array.
for( int indx = 0; indx < 10; ++indx )
{
delete ppArr[indx];
}
delete [] ppArr;
Note the order that I allocated this memory and then that I de-allocated it in the reverse order. This is because if we were to do the delete [] ppArr; first we would lose the array that tells us what our other pointers are. That chunk or memory would be given back to the system and so can no longer be reliably read.
int a=0;
int b=1;
int c=2;
ppArr = new int *[3];
ppArr[0] = &a;
ppArr[1] = &b;
ppArr[2] = &c;
This I think should be mentioned as well. Just because you are working with pointers does not mean that the memory those pointers point to was dynamically allocated. That is to say just because you have a pointer doesn't mean it necessarily needs to be delete. The array I created here is dynamically allocated but the pointers point to local instances of ints When we delete this we only need to delete the array.
delete [] ppArr;
return 0;
}
In the end dynamically allocated memory can be tricky and anyway you can wrap it up safely like in a smart pointer or by using stl containers rather then your own can make your life much more pleasant.
See boost pointer container for a container that does the automatic deletion of contained pointers for you, while maintaining a syntax very close to ordinary STL containers.
Pointers are pretty much just memory references and not spiffy little self-cleaning .net objects. Creating proper destructors for each class will make the deletion a little cleaner than massive loops throughout the code.
Let's take a (pseudocoded) real world example .Imagine that you had a class like this:
class Street
{
public:
Street();
~Street();
private:
int HouseNumbers_[];
}
typedef *Street StreetSign;
If you have an array of street signs, and you delete your array of streetsigns, that doesn't mean that you automatically delete the sreets. They re still there, bricks and mortar, they just don't have those signs pointing to them any more. You have got rid of those specific instances of pointers to the streets.
An array of pointers is (conceptually) a bit like an array of integers, it's an array of numbers representing the memory locations of various objects. It isn't the objects themselves.
If you delete[] the array of pointers, all you have done is delete an array of integers.
I think you're going to have to loop over I'm afraid.
I don't know why this was answered so confusingly long.
If you delete the array of pointers, you will free
the memory used for an array of usually ints.
a pointer to an object is an integer containing the adress.
You deleted a bunch of adresses, but no objects.
delete does not care about the content of a memory space,
it calls a destructor(s) and marks the mem as free.
It does not care that it just deleted a bunch of adresses
of objects, it merely sees ints.
That's why you have to cycle through the array first! and call delete
on every element, then you can delete the storage of the array itself.
Well, now my answer got somewhat long... .... strange... ;)
Edit:
Jason's answer is not wrong, it just fails to hit the spot. Neither
the compiler nor anything else in c(++) cares about you deleting stuff that is elsewhere
pointed to. You can just do it. Other program parts trying to use the deleted objects
will segfault on you. But no one will hinder you.
Neither will it be a problem to destroy an array of pointers to objects, when the objects
are referenced elsewhere.