Giving the size to an array with a variable - c++

I've been trying to give an array its size through a variable, but it's not working because "must have a constant value".
int processes[] = { 1, 2, 3 };
int n = sizeof processes / sizeof processes[0];
...
findavgTime(processes, n);
-------------------------------------------------
void findavgTime(int processes[], int n, int bt[])
{
int wt[n], tat[n]; //These two vars are giving me the error
}
Am I missing something?

As you've seen, you can declare an array with a non-constant size like this. You could, however allocate it dynamically using new:
int* wt = new int[n];
int* tat = new int[n];
Just don't forget that you need to delete[] these arrays when you're done.

You can allocate it on the heap like how Mureinik said, but you can also allocate it on the stack (as you were trying to do) with alloca() like this:
int* wt = (int*)alloca(n * sizeof(int));
int* tat = (int*)alloca(n * sizeof(int));
free() should not be called as it is allocated on the stack, not the heap.
Some say using alloca() is bad practice because if the call causes a stack overflow, program behavior is undefined. This shouldn't be a problem as long as the array isn't too long.

Related

What is the difference between given two lines of dynamic memory allocation in C++ ? Do they both create 10 sized array?

int *arr = new int(10);
int *arr = new int[10];
It is the code of dynamic memory allocation in c++.
But I am not getting What is the difference between these two.
For a simple example, let's talk about what happens on the stack.
int x(10)
This generally means assigning an value to an int named x.
int x[10]
This generally means creating an array named x of 10 elements.
So, when it come to dynamic memory, it's the same thing.
int* x=new int(10)
This creates a single integer on the heap and assigns it the value 10.
int* x=new int[10]
This creates an array of 10 integers on the heap.
int *arr = new int(10); allocates heap memory for a single integer, initialized to 10.
int *arr = new int[10]; allocates heap memory for an array of 10 integers, none of which are initialized to any specific value.
Keep it in mind: The ( ) and { } mainly used for initialization in declarations. And [ ] is mainly an indexing operator. So in the first statement, you are trying to allocate an int memory with 10 as the initial value. And in the second statement, you are trying to allocate a 10 int block array with no default initialization.

What is faster - using int *s = new int[size] or int s[size] + std::fill_n(s, size, 0);?

Im just wondering ... read about malloc and static allocation. It is obvious that static way is faster. But how about this: instead of doing:
int *s = new int[100];
I would write:
int s[100];
and then use:
std::fill_n(s, 100, 0);
will it be faster too? I mean, I have 2 operations, than just one:
int s[100]; and std::fill_n(s, 100, 0); instead of just int *s = new int[100];
These two expressions are not equivalent:
The first one allocates an array from dynamic store (also known as "the heap"),
The second one allocates an array in the automatic store (also known as "the stack").
The first expression does not value-initialize the array
The second expression fills the array with zeros explicitly
Generally speaking, stack operations are faster, because they are implemented in hardware: essentially, the allocation portion is free. The call of new[] and delete[], on the other hand, are also heavily optimized, so you would see very little difference in most situations.
If you wish to initialize the new array with zeros, you need to put parentheses after the array size, like this:
int *s = new int[100]();
// ^^

Pointers and dynamically allocated arrays in C++

I'm trying to get this clear up in my mind.
int* arrayA = new int[3];
int arrayB[3] = {1,2,3}
arrayA = arrayB;
Does the value of arrayB get copied over to arrayA?
Or does arrayA become a pointer to arrayB?
Naked new is evil, especially for arrays. Use std::vector if you need dynamic array and std::array if you need static one.1
Now the actual answer is simple. arrayA is a pointer. So it's made to point to arrayB. That has additional effect that:
you now leaked the allocated pointer.
attempt to delete arrayA will now crash or something else unpleasant, because you would be trying to free unallocated memory.
Actually while C++ allows assigning structures and classes, it does not support assigning arrays at all. Unless part of an object either managed as in std::vector or as array member as in std::array (note: std::array is C++11).
1 The main reason is that the containers guarantee the resources will be released in their destructors, so called RAII idiom, avoiding most opportunities for memory leaks and dangling references.
int* arrayA = new int[3];
arrayA now stores the address in memory of a different memory block thats large enough to contain 3 ints which is stored on the heap.
int arrayB[3] = {1,2,3};
arrayB is a block of memory thats large enough to contain 3 ints which is stored on the stack.
arrayA = arrayB;
Copies the address of the memory block that's stored on the stack into the variable arrayA. You have now lost the only reference to memory block stored on the heap, and have no way to free up the memory (a memory leak)
The memory stored on the stack and now pointed to by arrayA will not be safe to access when the current function returns. In particular returning arrayA (or arrayB) is not safe.
For
Does the value of arrayB get copied over to arrayA?
Nope. It will not copy arrayB to arrayA. If you want to do so, you can do like,
for (int i=0;i<3;i++) arrayA[i]=arrayB[i]; //This is two arrays has same value
does arrayA become a pointer to arrayB?
Yes. It become a pointer to array of arrayB. After arrayA = arrayB; statement, memory allocated in the first line can not be accessible and it is a leak.
arrayA=arrayB; result in copying the address of arrayB to arrayA. arrayA will start pointing to the arrayB. Check it using,
printf("\n Base address of A[%u] base address of B[%u]", arrayA, arrayB);
Hope this helps.
Array name represents the base address of the array.
arrayA=arrayB;
stores the base address of arrayB to arrayA. The further values can be accessed by incrementing the pointer arrayA.
i.e
*(arrayA) value is 1
*(arrayA+1) value is 2
*(arrayA+2) value is 3
The memory created should be freed at the last using
delete[] arrayA
Q. Does the value of arrayB get copied over to arrayA?
Ans. NO
Or
Q. does arrayA become a pointer to arrayB?
Ans YES.
But the memory chunk which you allocated using new is lost. As no one is having the address which was starting point of that chunk.
This is vindicated by this program :
#include<iostream>
using namespace std;
const int MAX=4;
int main(){
int* arrayA = new int[MAX];
for(int i=0;i<MAX;i++){ arrayA[i]=i; }
int arrayB[MAX] = {10,20,30,40};
arrayA = arrayB;
for(int i=0; i<MAX;i++){ cout<<" a["<<i<<"] = "<<arrayA[i]<<endl; }
return 0;
}
The output of this code is :
a[0] = 10
a[1] = 20
a[2] = 30
a[3] = 40
on
g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
which is true in general as well.
visualization of this is somewhat like this
arrayA-> [0][1][2][3]
arrayB-> [10][20][30][40]
Intially arrayA has address of [0] ( + sum extra memory on the negative indexes for size used by compiler to do the de-alloctation ).
after
arrayA=arrayB;
arrayA has address of [10];
suppose you call delete on arrayA what shall happen ??
*** Error in `./a.out': double free or corruption (out): 0x00007fff561281d0 ***
This is evident from the following code also
#include<iostream>
using namespace std;
const int MAX=4;
int main(){
int* arrayA = new int[MAX*2];
for(int i=0;i<MAX;i++){ arrayA[i]=i; }
int* arrayC = new int[MAX];
int j=0;
for(int i=MAX*100;i>=0;i-=10,j++){ arrayC[j]=i; }
arrayA = arrayC;
for(int i=0; i<MAX;i++){ cout<<" a["<<i<<"] = "<<arrayA[i]<<endl; }
delete[] arrayA;
return 0;
}
The out put is :
a[0] = 400
a[1] = 390
a[2] = 380
a[3] = 370
*** Error in `./a.out': free(): invalid next size (fast): 0x0000000002028040 ***
Aborted (core dumped)
Just pay attention to :
"invalid next size"
This clearly says about the size value written before the arrayA in the negative indexes.

Make array in cpp

I am trying to make a new array in my project
the code is:
#include <iostream>
using namespace std;
void makeArray( int *& arrayPtr, int size );
int main( )
{
int * arrPtr;
int size =10;
makeArray( arrPtr, size );
for(int j=0;j<size;j++)
{
cout<<arrPtr[j]<<endl;
}
}
void makeArray( int *& arrayPtr, int size )
{
int arr[size-1];
for(int i=0;i<size;i++)
{
arr[i]=0;
}
*&arrayPtr=*&arr;
}
According to the requirements i need to use the above "makeArray" method inorder to make the array.
When i run the code the output is garbage values not zero.....
any help will be appreciated
thank you
The way you are creating the array is on the stack, which means that it will not exist after the makeArray function finishes.
You will need to allocate the array on the heap.
So:
int arr[size-1];
should be:
int *arr = new int[size-1];
Also, I think you mean to do this in makeArray():
arrayPtr = arr;
Instead of:
*&arrayPtr=*&arr;
Which compiles but is more complex and is functionally the same thing in this context.
But you may prefer just returning an int* instead of taking a reference to the pointer.
Then when you are done using the array in main(), and set it to NULL just in case you accidentally use it again, like this:
for(int j=0;j<size;j++)
{
cout<<arrPtr[j]<<endl;
}
delete [] arrPtr;
arrPtr = NULL;
Why are you declaring a parameter as 'int *& arrayPtr'? Do you just need a pointer to an array? You should use 'int *arrayPtr' instead.
To answer your question, the problem is that you are declaring an array in the function makeArray's stack. Upon the completion of a function, that function's stack is destroyed, so you're passing the address of junk data. To avoid this, use dynamic memory allocation instead.
EDIT: Also, you should use memset instead of a for loop to zero an array. It's much faster.
The "arr" which you allocate in "makeArray()" is local. and when the functione is over the array is release. When you back to main you get garbage.
What you want to do, is to use the "new" operator to allocate this new array to be used in all program, unless you will free this memory by "delete".
so you can set your makeArray() to:
int* makeArray(int size )
{
int *arr = new[size];
for(int i=0;i<size;i++)
{
arr[i]=0;
}
return arr;
}
the in you main you need to initialize your arry by:
int * arrPtr = makeArray(10);
just don't forget to release this memory after you finsh:
delete[] arrPtr ;

What is the difference between an array and a dynamic array?

What is the difference between the following two types of array?
int array1[10];
int* array2 = new int[10];
The main difference is that a dynamic array is created on the heap. A dynamic array's size can be determined at runtime.
The difference in the below:
int x = 10;
int array1[10];
int *array2 = new char[x];
Is that array2 is pointing to the first element of an array and not the actual full array.
Note:
assert(sizeof(array1) == 40);
assert(sizeof(array2) == 4);
Memory on the heap that is created with new should eventually be destroyed using delete.
Since array2 is created on the heap, and is an array you will need to delete it with delete[] though.
Note: You can actually create a pointer to a full array and not just the first element:
int array1[10];
int *pointerToFirstElement = array1;
int (*pointerToFullArray)[10] = &array1;
int sizeOfFirstPointer = sizeof(pointerToFirstElement);
int sizeOfSecondPointer = sizeof(pointerToFullArray);
assert(sizeOfFirstPointer == sizeOfSecondPointer);//==4 since both are pointers
However what they point to have different sizes:
int sizeOfFirst = sizeof(*pointerToFirstElement);
int sizeOfSecond = sizeof(*pointerToFullArray);
assert(*sizeOfFirst == 4);
assert(*sizeOfSecond == 40);
A dynamic array is created from heap memory at run time and can be dynamically resized/freed as necessary with the new/delete keywords. An array is statically defined at compile time and will -always- take that amount of memory at all times.