Declaring an array in a loop - arrays

Is it possible to declare an array inside a loop. For some reasons I can not declare it before the loop since its length changes. I am wondering if I can re-declare/delete an array within the loop. I am using C++/CLI language.

Native c++ arrays, must have their size determined at compile-time if they are allocated on the stack, and so if you want to use native arrays, you'll have to allocate them with the new operator.
Unrecommended solution:
int rows = 1000;
int arr[] = new int[rows]; //new array with 1000 integers
int rows = 5;
delete arr; //don't forget to delete the previous allocation before re-sizing
int arr[] = new int[rows]; //new array with 5 integers
This however forces you to constantly be aware of allocations and de-allocations. That's why the standard and Microsoft gave you std::vector and cli::array.
The Managed way:
If you want your array to be on the managed heap, use cli::array:
cli::array<int> ^arr= gcnew cli::array<int>(1000); //new array with 1000 integers
Array::Resize(arr, 5); //resize arr to 5 integers
The unmanaged way:
If you want your array to be on the unmanaged heap (native C++), use std::vector:
std::vector<int> arr(1000); //new array with 1000 integers
arr.resize(5); //resize array to 5 integers

You could use Array::Resize method in each iteration (as eladidan says); or you could use a List<> class, add items in each iteration and finally call List<>::ToArray() to get the array you are looking for. Probably the first way would be more efficient but the second one is more convenient.

Related

Is there a way to dynamically increase an array size in C? [duplicate]

I am experimenting a little bit with gamestudio.
I am now making a shooter game.
I have an array with the pointers to the enemies. When an enemy is killed, I want to remove him from the list. And I also want to be able to create new enemies.
Gamestudio uses a scripting language named lite-C. It has the same syntax as C and on the website they say, that it can be compiled with any C compiler. It is pure C, no C++ or anything else.
I am new to C. I normally program in .NET languages and some scripting languages.
You can't. This is normally done with dynamic memory allocation.
// Like "ENEMY enemies[100]", but from the heap
ENEMY* enemies = malloc(100 * sizeof(ENEMY));
if (!enemies) { error handling }
// You can index pointers just like arrays.
enemies[0] = CreateEnemy();
// Make the array bigger
ENEMY* more_enemies = realloc(enemies, 200 * sizeof(ENEMY));
if (!more_enemies) { error handling }
enemies = more_enemies;
// Clean up when you're done.
free(enemies);
Once an array in C has been created, it is set. You need a dynamic data structure like a Linked List or an ArrayList
Arrays are static so you won't be able to change it's size.You'll need to create the linked list data structure. The list can grow and shrink on demand.
Take a look at realloc which will allow you to resize the memory pointed to by a given pointer (which, in C, arrays are pointers).
As NickTFried suggested, Linked List is one way to go.
Another one is to have a table big enough to hold the maximum number of items you'll ever have and manage that (which ones are valid or not, how many enemies currently in the list).
As far as resizing, you'd have to use a pointer instead of a table and you could reallocate, copy over and so on... definitely not something you want to do in a game.
If performance is an issue (and I am guessing it is), the table properly allocated is probably what I would use.
I wanted to lower the array size, but didn't worked like:
myArray = new int[10];//Or so.
So I've tried creating a new one, with the size based on a saved count.
int count = 0;
for (int i = 0; i < sizeof(array1)/sizeof(array1[0]); i++){
if (array1[i] > 0) count++;
}
int positives[count];
And then re-pass the elements in the first array to add them in the new one.
//Create the new array element reference.
int x = 0;
for (int i = 0; i < sizeof(array1)/sizeof(array1[0]); i++){
if (array1[i] > 0){ positives[x] = array1[i]; x++; }
}
And here we have a brand new array with the exact number of elements that we want (in my case).

How to convert static array to dynamic array in c?

Suppose say I have a static array
int a[10];
At some point the the program I want to insert 11th element.So it will throw error as Index out of range error.
So I want to create dynamic array a[]. without changing static array. And I want to take more input to array a[] during run time (means scalability).
Replace int a[10]; with int *a = malloc(10 * sizeof(int));. When you want to expand it to 11 elements, do a = realloc(a, 11 * sizeof(int));. If either of the previous two functions return null, then you ran out of memory and should treat it like the error that it is. Finally, where your original array would have gone out of scope, put free(a);.
I don’t think you can increase array size statically in C.
When it comes to static - we cannot increase the size of an array dynamically since we will define its size explicitly at the time of declaration itself.
However you can do it dynamically at runtime using the realloc() in stdlib.h header. but when you create an array dynamically using malloc().
The typical response in this situation is to allocate a new array of the larger size and copy over the existing elements from the old array, then free the old array.
There are some resources which may help you to understand this.
here

How we can insert array elements when array size is already fixed in C?

When ever I read differences between linked lists & arrays, I always saw on lot of sites that insertion of an element in to an array is very costly because we need to do lot of data moving. But one thing I always didn't understand is how we can create space for one more element while inserting, as the size of the array (or number of the elements in array) is fixed at compile time. Can any one please let me know how we can insert element into a fixed size array. And is there any concept called Dynamic array in C?
There is, indeed, the concept of a dynamic array. You just need a pointer and to reserve memory of the size you want with malloc. You need also to keep track of the number of elements you have.
int* my_array = malloc(10 * sizeof(int));
int n_used_elements = 0; // Need to keep track of the used elements and the size
int my_array_size = 10; // reserved size
However, when you exceed the number of elements in your array, you need to reserve the whole thing again and copy it again to the new reserved memory, which is also costly.
Usually, when using arrays for dynamically increasing and shrinking amounts of data, one of the most typical approaches goes with the following idea: when you exceed the size of your array, you double the size (i.e. you do not just add one more, but reserve for an extra number of elements in prevision you might need to increase the size of your array again), copy the elements of the old small one and keep going. Whenever you exceed, you double the size. On the other hand, to avoid wasting memory, if you have less than a certain amount of elements occupied, sometimes you half the size of the array.
Inserting a new element in an array is very costly because you have to shift all the elements after the inserted index one position to the right. The bigger the array, the bigger the cost of it (i.e. it is proportional to the size of an array). And you always need to consider the possibility of exceeding the size of the vector.
In C, there is no "native" concept of a dynamic array. You can create fixed length arrays via declaration:
int myArray[10];
Or dynamically via malloc/calloc:
int* myArray = malloc(10, sizeof(int));
The reason that "inserting" into a fixed array is so costly, is because you need to:
Create a new, bigger array.
Copy the old data into the new array.
Insert the new element into the appropriate spot in the new array.
Your options are to create your own storage mechanism (ie: stack, queue, linked list), or implement an existing implementation of such.
If you have an array like int a[10]; (and you use all 10 elements) it is not possible to resize it to fit another element.
For dynamic size you have to use a pointer int* a;, allocate memory youself with a = malloc(10*sizeof(int)); and take care of moving around elements when you insert in the middle.
There's no built-in dynamic array in C. If you need a dynamic array, you can't escape pointers.
typedef struct {
int *array;
size_t used;
size_t size;
} Array;
void insertArray(Array *a, int element) {
if (a->used == a->size) {
a->size *= 2; // double the size when exceeding the size of the array
a->array = (int *)realloc(a->array, a->size * sizeof(int));
}
a->array[a->used++] = element;
}
Check out this post for more details and examples.

How to implement a dynamic 2D array in C with known number colums

I am trying to create a 2d Array at compile time that has an unknown number of rows that i can dynamically allocate throughout the program but a specific number of columns as 8.
Something like ---->Elements[?][8];
If you have to use 2d array instead of list of array you gonna have to make a array
constant i = 1
foo[i][8]
and every time you want to expand that array
make temp_foo[i][8]
copy foo to temp_foo
delete foo
make foo[i++][8]
copy temp_foo to foo
But that's make confusing. and i think its better if use link list
struct node
{
foo[8]
node *next;
}
adding first element
node *element_head
element->foo = {add elements}
element->next = null
adding new element
node *temp
temp->foo = {add element}
temp->next = element_head
element_head= temp
Knowing the number of columns, and making only the number of rows dynamic you can either use a VLA or dynamic allocation. A VLA is straight forward:
int rows;
// get rows somehow
int table[rows][8];
Keeping in mind a VLA has automatic storage lifetime and will be removed from addressable memory once the enclosing scope expires. And they cannot be globals.
If your implementation doesn't support VLA's, automatic storage space is a concern, or you need a global variable for some nefarious purpose, you'll have to manage this dynamically (which it sounds like you want to do anyway). To do that, declare a pointer to an array of 8 elements, as such:
int rows;
// get rows somehow
int (*table)[8] = malloc(rows * sizeof(*table));
The rest is straight forward. You can reference your elements as table[i][j] for i in 0..rows-1 and j in 0..7. Just remember to free your allocation when finished:
free(table);
and don't reference it again.
As far as I know, you can't have foo[][8] in C. You might be able to hack around it by making a struct and casting a pointer to that struct to an array, as discussed here, but that is a somewhat fragile hack.
What you can do is change the definition of rows and columns in your problem space, so that, in order to access row i, column j, you would do foo[j][i] instead of foo[i][j].
In this case you could declare your array like this: <typename> * foo[8].
I'd go with this approach when the dimensions are unknown.
Assuming data type to be int.
int* a; //this will point to your 2D array
allocate it when you know the dimensions (ROW, COL):
a = malloc(sizeof(int)*ROW*COL);
and access it like
a[ROW*i + j] = value // equivalent of a[i][j]
I think it will not be created when you are not passing any value at compile time, my suggestion is to use dynamic memory allocation as you don't know how many rows

Dynamic Array printing

I am trying to print a dynamic array, but I am having trouble with the bounds for the array.
For a simple example, lets say I'm trying to loop through an array of ints. How can I get the size of the array? I was trying to divide the size of the array by the size of the type like this sizeof(list)/sizeof(int) but that was not working correctly. I understand that I was trying to divide the size of the pointer by the type.
int *list
// Populate list
int i;
for(i = 0; i < ????; i++)
printf("%d", list[i]);
With dynamic arrays you need to maintain a pointer to the beginning address of the array and a value that holds the number of elements in that array. There may be other ways, but this is the easiest way I can think of.
sizeof(list) will also return 4 because the compiler is calculating the size of an integer pointer, not the size of your array, and this will always be four bytes (depending on your compiler).
YOU should know the size of the array, as you are who allocated it.
sizeof is an operator, which means it does its job at compile time. It will give you the size of an object, but not the length of an array.
So, sizeof(int*) is 32/62-bit depending on architecture.
Take a look at std::vector.
There is no standardized method to get the size of allocated memory block. You should keep size of list in unsigned listSize like this:
int *list;
unsigned listSize;
list = malloc(x * sizeof(int));
listSize = x;
If you are coding in C++, then it is better to use STL container like std::vector<>
As you wrote, you really did tried to divide the size of a pointer since list is declared as a pointer, and not an array. In those cases, you should keep the size of the list during the build of it, or finish the list with a special cell, say NULL, or anything else that will not be used in the array.
Seeing some of the inapropriate links to C++ tools for a C question, here is an answer for modern C.
Your ideas of what went wrong are quite correct, as you did it you only have a pointer, no size information about the allocation.
Modern C has variable length arrays (VLA) that you can either use directly or via malloc. Direcly:
int list[n];
and then your idea with the sizeof works out of the box, even if you changed your n in the mean time. This use is to be taken with a bit of care, since this is allocated on the stack. You shouldn't reserve too much, here. For a use with malloc:
int (list*)[n] = malloc(*list);
Then you'd have to adapt your code a bit basically putting a (*list) everywhere you had just list.
If by size you mean the number of elements then you could keep it in a counter that gets a ++ each time you push an element or if you dont mind the lost cycles you could make a function that gets a copy of the pointer to the first location, runs thru the list keeping a counter until it finds a k.next==null. or you could keep a list that as a next and a prev that way you wouldnt care if you lost the beginning.

Resources