Elements retained even after using delete[] - c++

My code is :
#include <iostream>
using namespace std;
int main() {
// your code goes here
int* a;
a = new int[5];
for(int i = 0; i < 5; i++)
cin>>a[i];
for(int i = 0; i < 5; i++)
cout<<a[i]<<" ";
delete[] a;
cout<<"NEW MEM ";
a = new int[5];
for(int i = 0; i < 5; i++)
cout<<a[i]<<" ";
return 0;
}
INPUT : 1 2 14 4 5 and
OUTPUT : 1 2 14 4 5 NEW MEM 0 0 14 4 5
Please explain why i am not getting OUTPUT : 1 2 14 4 5 NEW MEM 0 0 0 0 0

Perhaps you were expecting that new int[5] would zero-initialise the new block of memory.
Well, it doesn't! And that's pretty much that. C++ doesn't do things you didn't ask for, because if you didn't want them, that's an unnecessary performance hit.
It looks like your new memory block just so happens to be found at the same place as the last one, and now you're [partially] observing the values left behind from the last one. Technically these values are unspecified, and reading them means your program has undefined behaviour. You have to provide your own fresh values for these new array elements before you can use them for anything truly meaningful.
Or perhaps you were expecting the delete[] to zero-initialise the dying block of memory.
That doesn't happen either. There's really no point in zeroing-out objects just as they are about to wither out of existence. Again, C++ won't waste time on things like this.
You can make the zero-initialisation happen with new int[5]() but I don't see a good reason to do so here.

Because with:
a = new int[5];
You are not (default) initializing your array to zeros nor any other value as pointed out in the comments below. You are only allocating space for five ints on the free-store and printing out the values of an uninitialized array which is undefined behavior.
Initialize your array values to 0:
a = new int[5] {0};
or:
a = new int[5] {};
Or provide values for all the elements:
a = new int[5] { 1, 2, 14, 4, 5 };

Related

C++ Why make new int is error?

Why my code error ?
int *x ;
x = new int[5];
x[0] = 3;
x[1] = 4;
x[2] = 5;
x[3] = 1;
x[4] = 2;
x[5] = 11;
x[6] = 90;
int *y ;
y = new int[5];
cout << "if no error, then this command should be run" << endl;
but the output is :
Process exited after 0.07883 seconds with return value 3221226356
Press any key to continue . . .
Before writing code, think of the logic for a moment. If you could allocate space for 5 ints and then straightaway carry on storing 10 (or anything beyond 5 elements, for that matter), what's the point of allocating anything, in first place?
What you're seeing here is memory overrun, which invokes undefined behavior. Don't do that.
To elaborate, on 0-based indexing system, the valid index for the above case will be 0 to 4, anything beyond that is going to access out of bound memory, which invokes the UB.
You allocate 5 integers then try to store 7.
Why do you expect that to work?
You can't access the 5 and 6 position of an array of length 5.
You only can access x[0], x[1], x[2],x[3] and x[4] positions.
So if an array is of n positions you can access up to position n-1 because the first position is 0.
Why make new int is error
There is nothing wrong with make new int. The problem is with the size of your array at declaration.
Let's look at your code for a moment:
int *x ;
x = new int[5];
x[0] = 3;
x[1] = 4;
x[2] = 5;
x[3] = 1;
x[4] = 2;
x[5] = 11;
x[6] = 90;
You start by declaring a pointer int variable in the first line.
You then assign exactly 5 consecutive spaces in memory, with x pointing to the first one.
You then assign values to the 5 blocks of memory, starting at 0 and going up to 4, which is valid, as 0-4 is 5 blocks of memory is what the compiler has initialy allocated for you in memory.
Then, you try to store 11 in x[5] and 90 in x[6]. This is where undefined behaviour occurs.
When you try to move outside of the index specified in your array, your program is trying to access memory that it should not, because the compiler has only allotted a fixed number of spaces in memory initially. You do not know what the memory space that comes right after x[4] has stored in it, if anything at all, because the compiler has only allotted you memory for an array of index 0 to 4. x[5] may be empty, in which your program sill continue running, or it may be used in some other process of your machine, and trying to access that is disallowed, which leads to a segmentation fault in your case.
This is why it is called undefined behaviour; when an array index that is outside of the array size declared initially may point to a memory space that is or is not empty. If it is empty, then the program will continue running (this is wrong), but if it is not empty, then your program will terminate due to a runtime error: segmentation fault.
To fix this, change your array size to:
x = new int [7];
So that the compiler will find 7 consecutive spaces of memory instead of 5.

c++ 2D array allocation

Could someone please explain what each line is really doing here. I know overall it allocates 4 spaces, but I don't understand the details.
int** arrayArray;
arrayArray= new int*[4];
for (int x = 0; x < 4; ++x)
{ arrayArray[x] = new int[4];}
Your array is a 2D array, so it size is in forms of "x by y". The total ints your array contains will be x*y. I will call x as the row number and y as the column number.
It seems like you need a array with total 4 ints, so your row number and column number should have a product of 4, for example 2x2. Keep in mind that the following answer is dealing with a 4x4 array, which has 16 total ints.
Allocation:
int** arrayArray;
This line decelar a variable arrayArray, which is a pointer of ( pointer of int ). Like
(arrayArray) -> * -> int
So arrayArray[0] gives you a pointer of int, and arrayArray[0][0] therefore give you an int (which is in the array).
arrayArray = new int*[4];
This line allocate a space that can contain 4 pointers of int, and set the arrayArray to point to that space (don't forget that arrayArray is a pointer of a pointer of int. ).
Here the 4 means row number.
for (int x = 0; x < 4; ++x)
arrayArray[x] = new int[4];
For every pointer in arrayArray, set it to point to a space for 4 ints.
Here the 4 in new int[4] means column number.
So the structure of this array will be something like
Deallocation (free):
Notice that arrayArray by it self is just a pointer to 4 other pointer. If you want to free the entire array, you don't just free the space for the 4 pointers. You need to free every space these pointer points to, else you will cause memory leak. For example you want to free the entire array, it is just the reverse of allocation, first free all the space arrayArray points to:
for (int x = 0; x < 4; ++x)
delete[] arrayArray[x];
In C++, if you want to delete a space allocated by new something[], you need delete[] instead of delete.
Then free the array itself:
delete[] arrayArray;
int** arrayArray;
arrayArray= new int*[4];
The above code initializes 4 locations that can hold pointers to 4 int*
The next couple of lines allocate 4 int spaces for each int*, so a total of 4*4=16 integer spaces.
for (int x = 0; x < 4; ++x)
{ arrayArray[x] = new int[4];}
Now as per your comment, you want only 4 integer spaces. So that means your 2d array would be 2x2.
So your code should look something like:
int** arrayArray;
arrayArray= new int*[2];
for (int x = 0; x < 2; ++x)
{ arrayArray[x] = new int[2];}
This way you will only allocate 2 int* locations and 2 int spaces that they can point to.

I don't understand how to create and use dynamic arrays in C++

Okay so I have;
int grid_x = 5
int * grid;
grid = new int[grid_x];
*grid = 34;
cout << grid[0];
Should line 3 create an array with 5 elements? Or fill the first element with the number 5?
Line 4 fills the first element, how do I fill the rest?
Without line 4, line 5 reads "-842150451".
I don't understand what is going on, I'm trying to create a 2 dimensional array using x and y values specified by the user, and then fill each element one by one with numeric values also specified by the user. My above code was an attempt to try it out with a 1 dimensional array first.
The default C++ way of creating a dynamic(ally resizable) array of int is:
std::vector<int> grid;
Don't play around with unsafe pointers and manual dynamic allocation when the standard library already encapsulates this for you.
To create a vector of 5 elements, do this:
std::vector<int> grid(5);
You can then access its individual elements using []:
grid[0] = 34;
grid[1] = 42;
You can add new elements to the back:
// grid.size() is 5
grid.push_back(-42);
// grid.size() now returns 6
Consult reference docs to see all operations available on std::vector.
Should line 3 create an array with 5 elements?
Yes. It won't initialise them though, which is why you see a weird value.
Or fill the first element with the number 5?
new int(grid_x), with round brackets, would create a single object, not an array, and specify the initial value.
There's no way to allocate an array with new and initialise them with a (non-zero) value. You'll have to assign the values after allocation.
Line 4 fills the first element, how do I fill the rest?
You can use the subscript operator [] to access elements:
grid[0] = 34; // Equivalent to: *(grid) = 34
grid[1] = 42; // Equivalent to: *(grid+1) = 42
// ...
grid[4] = 77; // That's the last one: 5 elements from 0 to 4.
However, you usually don't want to juggle raw pointers like this; the burden of having to delete[] the array when you've finished with it can be difficult to fulfill. Instead, use the standard library. Here's one way to make a two-dimensional grid:
#include <vector>
std::vector<std::vector<int>> grid(grid_x, std::vector<int>(grid_y));
grid[x][y] = 42; // for any x is between 0 and grid_x-1, y between 0 and grid_y-1
Or might be more efficient to use a single contiguous array; you'll need your own little functions to access that as a two-dimenionsal grid. Something like this might be a good starting point:
template <typename T>
class Grid {
public:
Grid(size_t x, size_t y) : size_x(x), size_y(y), v(x*y) {}
T & operator()(size_t x, size_t y) {return v[y*size_x + x];}
T const & operator()(size_t x, size_t y) const {return v[y*size_x + x];}
private:
size_t size_x, size_y;
std::vector<T> v;
};
Grid grid(grid_x,grid_y);
grid(x,y) = 42;
Should line 3 create an array with 5 elements? Or fill the first element with the number 5?
Create an array with 5 elements.
Line 4 fills the first element, how do I fill the rest?
grid[n] = x;
Where n is the index of the element you want to set and x is the value.
Line 3 allocates memory for 5 integers side by side in memory so that they can be accessed and modified by...
The bracket operator, x[y] is exactly equivalent to *(x+y), so you could change Line 4 to grid[0] = 34; to make it more readable (this is why grid[2] will do the same thing as 2[grid]!)
An array is simply a contiguous block of memory. Therefore it has a starting address.
int * grid;
Is the C representation of the address of an integer, you can read the * as 'pointer'. Since your array is an array of integers, the address of the first element in the array is effectively the same as the address of the array. Hence line 3
grid = new int[grid_x];
allocates enough memory (on the heap) to hold the array and places its address in the grid variable. At this point the content of that memory is whatever it was when the physical silicon was last used. Reading from uninitialised memory will result in unpredictable values, hence your observation that leaving out line 4 results in strange output.
Remember that * pointer? On line four you can read it as 'the content of the pointer' and therefore
*grid = 34;
means set the content of the memory pointed to by grid to the value 34. But line 3 gave grid the address of the first element of the array. So line 4 sets the first element of the array to be 34.
In C, arrays use a zero-based index, which means that the first element of the array is number 0 and the last is number-of-elements-in-the-array - 1. So one way of filling the array is to index each element in turn to set a value to it.
for(int index = 0; index < grid_x; index++)
{
grid[index] = 34;
}
Alternatively, you could continue to use a pointer to do the same job.
for(int* pointerToElement = grid; 0 < grid_x; grid_x-- )
{
// save 34 to the address held by the pointer
/// and post-increment the pointer to the next element.
*pointerToElement++ = 34;
}
Have fun with arrays and pointers, they consistently provide a huge range of opportunities to spend sleepless hours wondering why your code doesn't work, PC reboots, router catches fire, etc, etc.
int grid_x = 5
int * grid;
grid = new int[grid_x];
*grid = 34;
cout << grid[0];
Should line 3 create an array with 5 elements? Or fill the first
element with the number 5?
Definitely the former. With the operator "new" you are allocating memory
Line 4 fills the first element, how do I fill the rest?
Use operator [], e.g.:
for int (i=0; i < grid_x; i++) { //Reset the buffer
grid[i] = 0;
}
Without line 4, line 5 reads "-842150451".
You are just reading uninitialized memory, it could be any value.
I don't understand what is going on, I'm trying to create a 2
dimensional array using x and y values specified by the user, and then
fill each element one by one with numeric values also specified by the
user. My above code was an attempt to try it out with a 1 dimensional
array first.
Other users explained how to use vectors. If you have to set only once the size of your array, I usually prefer boost::scoped_array which takes care of deleting when the variable goes out of scope.
For a two dimensional array of size not known at compile time, you need something a little bit trickier, like a scoped_array of scoped_arrays. Creating it will require necessarily a for loop, though.
using boost::scoped_array;
int grid_x;
int grid_y;
///Reading values from user...
scoped_array<scoped_array<int> > grid(new scoped_array<int> [grid_x]);
for (int i = 0; i < grid_x; i++)
grid[i] = scoped_array<int>(new int[grid_y] );
You will be able then to access your grid elements as
grid[x][y];
Note:
It would work also taking scoped_array out of the game,
typedef int* p_int_t;
p_int_t* grid = new p_int_t [grid_x];
for (int i = 0; i < grid_x; i++)
grid[i] = new int[grid_y];
but then you would have to take care of deletion at the end of the array's life, of ALL sub arrays.

sorting gives wrong output for the element at last position

I am trying to clear some basic concepts os programming. I preferred doing sorting for this.
Below is my code:
#include<stdio.h>
#include<malloc.h>
#include <string.h>
main()
{
int array[9]={5,2,7,4,7,6,9,8,1,3};
int min,i,j,temp;
for(i=0;i<10;i++)
{
for(j=0;j<=10;j++)
{
if(array[i]<array[j])
{
temp=array[j];
array[j]=array[i];
array[i]=temp;
}
}
}
printf("\n");
for(i=0;i<10;i++)
{
printf("%d ", array[i] );
}
printf("\n");
}
And the output is :
1 2 4 5 6 7 7 8 9 9
which is unexpected. It must be
1 2 3 4 5 6 7 7 8 9
Could some one help me to know why this strange behavior at the end of the array. Why it repeats "9" and Where has "3" lost ?
Also i appreciate if some one tell me name of best sorting (Mostly i have heard of Bubble and quick sort, but why and what is the difference that i don't know). Please dont tell me about in built functions (like qsort() and etc.) because the objective is to clear concepts
You can any language to explain c/c++/ or even algorithm. Thanks
for(j=0;j<=10;j++) will give you undefined behaviour since you're accessing outside the array bounds with your subsequent array[j].
int array[9]={5,2,7,4,7,6,9,8,1,3}; is also unbalanced, you need int array[10] since you have 10 elements in your initialiser list. Better still, let the compiler do the work for you and write int array[]. This is why 3 is currently omitted from your output (notwithstanding the undefined behaviour).
array[9]; i < 10; j <= 10. array index out of bounds. undefined behaviour.
i and j should be checked like i < 9 and j < 9
int array[9]={5,2,7,4,7,6,9,8,1,3};
And you have 10 elements in that array.
You specify an array of 9 elements, and yet you have 10 elements in the initialiser and in your outer loop:
int array[9]={5,2,7,4,7,6,9,8,1,3};
// ^- this is not the last index, but the number of elements!
for(i=0;i<10;i++)
And here you iterate up to index 10, which is the 11th element (index 0 is the first):
for(j=0;j<=10;j++)
//^- when j is 10 this is still true, but there is no array[10]
To fix, change to the following:
int array[] = {5,2,7,4,7,6,9,8,1,3};
// ^- leave empty and let the compiler count the elements
const int array_len = sizeof(array) / sizeof(*array);
// length: ^- whole array / ^- one element
for (i = 0; i < array_len; ++i) {
for (j = 0; j < array_len; ++j) {
Firstly, any code should be added using the code button so that it is formatted properly and easy to read.
Secondly, you're array is too small. It's size is 9 but you have 10 items.

C++ : iterating the vector

I'm very new to C++ and I'm trying to learn the vector in C++..
I wrote the small program as below. I like to foreach(var sal in salaries) like C# but it doesn't allow me to do that so I googled it and found that I have to use iterator.. Im able to compile and run this program but I dont get the expected output.. I'm getting "0 0 0 0 0 0 1 2 3 4 5 6 7 8 9" instead of "0 1 2 3 4 5 6 7 8 9"..
Could anyone please explain me why? Thanks.
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
void show(int i)
{
cout << i << " ";
}
int main(){
vector<int> salaries(5);
for(int i=0; i < 10; i++){
salaries.push_back(i);
}
for_each(salaries.begin(), salaries.end(), show);
}
You created a vector with 5 elements, then you push 10 more onto the end. That gives you a total of 15 elements, and the results you're seeing. Try changing your definition of the vector (in particular the constructor call), and you'll be set. How about:
vector<int> salaries;
This code creates a vector with a size of 5, and with each of those 5 elements initialized to their default value (0):
vector<int> salaries(5);
push_back inserts a new element, so here, you insert 10 new elements, ending up with a vector with 15 elements:
for(int i=0; i < 10; i++){
salaries.push_back(i);
}
You can create your vector like this instead:
vector<int> salaries;
and you'll get a vector with size 0.
Alternatively, you could initialize it with size 10, and then overwrite each element, instead of inserting new ones:
vector<int> salaries(10);
for(int i=0; i < 10; i++){
salaries[i] = i;
}
In some cases, it may be more efficient to write something like this:
vector<int> salaries; // create a vector with size 0
// allocate space for 10 entries, but while keeping a size of 0
salaries.reserve(10);
for(int i=0; i < 10; i++){
// because we reserved space earlier, these new insertions happen without
// having to copy the vector contents to a larger array.
salaries.push_back(i);
}
When you declare salaries(5), it's adding 5 entries into the vector with values of 0. Then your loop adds 0..9. Therefore you have 15 elements in your vector instead of just 10. Try declaring the vector without the 5.
vector<int> salaries;
vector<int> salaries(5); means, that you are creating the vector which contains 5 int objects from the start, and each int object is initialized with default constructor, and in the case of int contructor sets zero value. That's why you have 5 zero integers at the beginning of the vector container.
#Michael: Which book is that? I'd say
it's wrong. Using resize() is a good
practice if you know in advance how
big you need the vector to be, but
don't set the size at creation unless
you need the vector to contain
default-initialized values.
You can also reserve some capacity in the array in advance which is subtely different than re-size. Reserving simply reserves "at least" that much capacity for the vector (but does not change the size of the vector), while resize adds\removes elements to\from the vector to make it the requested size.
vector<int> salaries(5);
This creates a vector of 5 zeros for its elements. [0, 0, 0, 0, 0]
for(int i=0; i < 10; i++){
salaries.push_back(i);
}
This adds 10 more elements at the end ranging from 0 to 9 [0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Finally, I don't recommend using foreach so much. Functional programming has the downside of decentralizing code. It is extremely useful in some cases, but for these cases, and especially considering how you're starting out, I'd recommend:
for (vector<int>::const_iterator it = salaries.begin(), end = salaries.end(); it != end; ++it){
salaries.push_back(i);
}
Using this technique, you'll be able to iterate through any collection in the standard library without having to write separate functions or function objects for the loop body.
With C++0x you'll get a lot of goodies to make this easier:
for (int salary: salaries)
cout << salary << endl;
There's also BOOST_FOR_EACH already which is almost as easy if you can use boost.