C++ 3d array - dynamic memory allocation aligned in one line - c++

i have a quite weird question which probably has no practical use but the answers bothers me a lot. I tried to mess around today a little bit with arrays and how they are allocated in memory using this code: (Compiler Xcode 4 btw, 4 byte integer)
int ***c;
int size_x = 0;
int size_y = 0;
int size_z = 0;
cout << "Enter x: " << endl;
cin >> size_x;
cout << "Enter y: " << endl;
cin >> size_y;
cout << "Enter z: " << endl;
cin >> size_z;
c = new int**[size_x];
for (int i = 0; i < size_x; ++i) {
*(c+i) = new int*[size_y];
for (int j = 0; j < size_y; ++j) {
*(*(c+i)+j) = new int[size_z];
}
}
for (int i = 0; i < size_x; ++i) {
for (int j = 0; j < size_y; ++j) {
for (int k = 0; k < size_z; ++k) {
cout << (*(*(c+i)+j)+k) << endl;
//cout << &c[i][j][k] << endl;
}
}
}
delete [] c;
When i enter now: 3, 2 and 4 i get the following output in the console:
0x100100a60
0x100100a64
0x100100a68
0x100100a6c
0x100100a70
0x100100a74
0x100100a78
0x100100a7c
0x100100a90
0x100100a94
0x100100a98
0x100100a9c
0x100100aa0
0x100100aa4
0x100100aa8
0x100100aac
0x100100ac0
0x100100ac4
0x100100ac8
0x100100acc
0x100100ad0
0x100100ad4
0x100100ad8
0x100100adc
What my question is now, if we look at the output, than we see that mostly, the memory is aligned every 4 bytes but sometimes we see a bigger step like from 0x100100a7c to
0x100100a90 .
Is this normal and how can i prevent this? Why is this? Is there a possibility to force c to align my memory as a constant line? (I'm not native english so sorry for that but i don't know how to say it better)
Its just for general understanding :-)
Thank u!
P.S. is it enough to use delete [] once btw or do i have to go through each of the 3 memory blocks and delete [] there the whole array? EDIT:
I delete memory now like this and it works pretty good:
cout << "Free Memory" << endl;
for (int i = 0; i < m_sx; ++i) {
for (int j = 0; j < m_sy; ++j) {
delete [] m_array[i][j];
//delete [] (*(*(m_array)+j)+k);
}
delete [] m_array[i];
}
delete [] m_array, m_array = NULL;

Yes, this is normal. The memory is aligned, btw., it's just not contiguous because subsequent calls to new do not make this guarantee. And yes, you can allocate the entire 3-d array in a single, contiguous buffer:
int *A = new int[size_x * size_y * size_z];
or, safer
std::vector<int> A(size_x * size_y * size_z);
and then index it with
int element = A[i * size_z * size_y + j * size_z + k]
to get the element at (i,j,k).
This is, in fact, very useful, as it gives you multidimensional arrays with little overhead, preserving locality of reference and preventing indirection. Also, the error handling for this allocation scheme is much simpler so you run less of a risk of memory leaks. Any good matrix library will be implemented this way. For C++, that includes Boost.MultiArray.
As for deallocation: yes, you need multiple calls to delete[] in your present scheme.

Heres a routine which allocates the 3D array of dimension N1 x N2 x N3 in contiguous memory space while allowing you the a[i][j][k] syntax for operator access. The array is dynamic but continuous so it's a huge plus over the vector<> approach and loops of new[] calls.
template <class T> T ***Create3D(int N1, int N2, int N3)
{
T *** array = new T ** [N1];
array[0] = new T * [N1*N2];
array[0][0] = new T [N1*N2*N3];
int i,j,k;
for( i = 0; i < N1; i++) {
if (i < N1 -1 ) {
array[0][(i+1)*N2] = &(array[0][0][(i+1)*N3*N2]);
array[i+1] = &(array[0][(i+1)*N2]);
}
for( j = 0; j < N2; j++) {
if (j > 0) array[i][j] = array[i][j-1] + N3;
}
}
cout << endl;
return array;
};
template <class T> void Delete3D(T ***array) {
delete[] array[0][0];
delete[] array[0];
delete[] array;
};
And later in your implementation routine...
int *** array3d;
int N1=4, N2=3, N3=2;
int elementNumber = 0;
array3d = Create3D<int>(N1,N2,N3);
cout << "{" << endl;
for (i=0; i<N1; i++) {
cout << "{";
for (j=0; j<N2; j++) {
cout << "{";
for (k=0; k<N3; k++) {
array3d[i][j][k] = elementNumber++;
cout << setw(4) << array3d[i][j][k] << " ";
}
cout << "}";
}
cout << "}";
cout << endl ;
}
cout << "}" << endl;
Delete3D(array3d);
Gives the output:
{
{{ 0 1 }{ 2 3 }{ 4 5 }}
{{ 6 7 }{ 8 9 }{ 10 11 }}
{{ 12 13 }{ 14 15 }{ 16 17 }}
{{ 18 19 }{ 20 21 }{ 22 23 }}
}

Since this is tagged C, here is also a C answer. Since C99 multidimensional arrays can be handled quite efficiently, even if the sizes are dynamic:
double c[size_x][size_y][size_z];
This allocates the matrix contiguously on the stack. Matrix elements are accessed by c[i][j][k] and the compiler does all the indexing arithmetic for you. If you fear that this could lead to SO, you can easily call malloc with it:
double (*c)[size_y][size_z] = malloc(sizeof(double[size_x][size_y][size_z]));

The issue is not that your memory isn't aligned ... the requirement by the C++ specification for a call to new and new[] is that it passes back a pointer pointing to contiguous memory that is properly aligned for the platform and the size of the object requested.
Your problem is that you are not allocating the entire buffer for the array with a single call to new[], but rather with multiple calls to new[]. Therefore while each call to new will return aligned and contiguous memory, the multiple calls to new[] are not required to return memory buffers that themselves are contiguously allocated. For example, each call to new[] returns aligned memory, but as you noted, there can be "gaps" in the start of each memory array that new returns. The reason for these "gaps" can have multiple reasons, and really depends on how the underlying OS is allocating memory for your program.
If you do not want to have any "gaps" in each array, then you will need to allocate the entire buffer with a single call to new.
Finally, to answer your question about delete[], yes, because you did not allocate the entire memory buffer with a single call to new[], you cannot delete your array with a single call to delete[]. Every call to new[] must be paired with a call to delete[] since those were separate memory allocations.

Yes this is normal.
You allocate data row by row; The only thing you can be sure is that data will be contiguous on each row.

Related

segmentation fault with pointer array

I am a getting a segment fault when trying to input data for my array of pointers. Im pretty new to coding so any help would be great. My task was to make an array of pointers then display, swap them around and than sort them
#include <iostream>
using namespace std;
float getValueFromPointer(float* thePointer)
{
return *thePointer;
}
float* getMinValue(float* a, float* b)
{
if (*a < *b)
{
return a;
}
else
{
return b;
}
}
int main()
{
int arraySize;
cout << "Enter the array size: ";
cin >> arraySize;
float** speed = new float*[arraySize]; // dynamically allocated array
for(int i = 0; i < arraySize; i++)
{
cout << "Enter a float value: ";
cin >> *speed[i];
}
// Core Requirement 2
for (int i = 0; i < arraySize; i++)
{
float value = getValueFromPointer(*speed+i);
cout << "The value of the element " << i << " is: ";
cout << value << endl;
}
//float *pointerToMin = getMinValue(&speed[0], &speed[arraySize - 1]);
//cout << *pointerToMin << endl;
delete [] speed;
speed = NULL;
return 0;
}
You’ve only allocated space for the outer array but you need to also allocate space for each of the internal floats.
So before calling this line:
cin >> *speed[i];
You need to first allocate space for it:
speed[i] = new float;
Your problem is that you've allocated an array of float pointers. You need to allocate an array of floats. So currently you have no memory allocated for the actual floats. If you do this, you'll allocate that memory:
float *speed = new float[arraySize];
You don't have any need for a 2D/jagged array that I can see. If you start with the code above, the compiler errors should lead you right in the direction. (Basically you will start removing * from a lot of places in your code.)
EDIT
Based on your requirement that I misunderstood, a possible approach is the following. The other answer (the one that isn't mine) makes sense in broader scenarios than this, but hopefully this is sort of another angle to think about that rather arbitrary problem you're trying to solve:
int main()
{
float *pFloats = new float[10];
float **ppFloats = new float*[10];
//assign float values and pointers to them in same loop
for (int i = 0; i < 10; i++)
{
pFloats[i] = i;
ppFloats[i] = &pFloats[i];
}
//swap two arbitrary pointers
float *pTemp = ppFloats[4];
ppFloats[4] = ppFloats[5];
ppFloats[5] = pTemp;
//print our float array
for (int i = 0; i < 10; i++)
printf("%f\n", pFloats[i]);
//print our float array *through* our pointers
for (int i = 0; i < 10; i++)
printf("%f\n", *ppFloats[i]);
delete[] ppFloats;
delete[] pFloats;
}
Ignore the hard-coded constants, etc...The point here is that I've created a contiguous memory area for the floats, and then created an array of float pointers on top of it. Note that I can sort my pointer array with zero impact on the original array. There are much smarter ways to do this, but...looks like you're learning about raw pointers, so...
Contrast with the other answer which creates jagged memory for the floats (1 at a time, on demand, not necessarily contiguous).

Why am I seeing different behavior between arrays allocated on the heap and the stack?

I am inspecting the behavior of two 2D arrays in C++, one allocated from the stack, and one allocated from the heap.
I create two, 2D arrays of the same shape, and populate those arrays with some data. Then I attempt to read the arrays in two different methods, the first being with the simple array index format "Arr[ROW][COLUMN]". Then I read the arrays using a pointer dereference, and I get two different results for the heap allocated array, but identical results for the stack allocated array. I am trying to understand why the results differ. I would appreciate any clarification that someone can provide. Thanks in advance.
The code I am running is below:
#include <iostream>
using namespace std;
int main(){
int rows = 6;
int columns = 3;
// allocate from the stack.
double q[rows][columns];
// allocate from the heap.
double ** a;
a = new double*[rows];
for(int i = 0; i < rows; ++i){
a[i] = new double[columns];
}
// populate the arrays.
for(int i = 0; i < rows; ++i){
for(int j = 0; j < columns; ++j){
a[i][j] = columns*i+j;
q[i][j] = columns*i+j;
}
}
cout << "*****************" << endl;
cout << "Array indexing method." << endl;
cout << "*****************" << endl;
// print the heap allocated array using array indexing.
for(int i = 0; i < rows; ++i){
for(int j = 0; j < columns; ++j){
cout << a[i][j] << '\t';
}
cout << endl;
}
cout << "*****************" << endl;
// print the stack allocated array using array indexing.
for(int i = 0; i < rows; ++i){
for(int j = 0; j < columns; ++j){
cout << q[i][j] << '\t';
}
cout << endl;
}
cout << "*****************" << endl;
cout << "Pointer dereferencing method." << endl;
cout << "*****************" << endl;
// print the heap allocated array.
for(int i = 0; i < rows; ++i){
for(int j = 0; j < columns; ++j){
cout << *(&a[0][0] + columns*i + j) << '\t';
}
cout << endl;
}
cout << "*****************" << endl;
// print the stack allocated array.
for(int i = 0; i < rows; ++i){
for(int j = 0; j < columns; ++j){
cout << *(&q[0][0] + columns*i + j) << '\t';
}
cout << endl;
}
cout << "*****************" << endl;
// release the memory allocated to the heap.
for(int i = 0; i < rows; ++i){
delete[] a[i];
}
delete a;
return 0;
}
And the results I obtain are:
*****************
Array indexing method.
*****************
0 1 2
3 4 5
6 7 8
9 10 11
12 13 14
15 16 17
*****************
0 1 2
3 4 5
6 7 8
9 10 11
12 13 14
15 16 17
*****************
Pointer dereferencing method.
*****************
0 1 2
0 3 4
5 0 6
7 8 0
9 10 11
0 12 13
*****************
0 1 2
3 4 5
6 7 8
9 10 11
12 13 14
15 16 17
*****************
And I can see that in the third block of output, the heap allocated array isn't being read properly, but the stack allocated array is.
Thanks again.
&q[0][0] gives you a pointer to the first double in a block containing rowsxcolumns doubles. While &a[0][0] gives you a pointer the first double in a block containing columns doubles (you've allocated it using a[0] = new double[columns];, remember?). So accessing it columns*i + j will be out of bounds and will triggers Undefined Behavior.
Arrays are usually a single allocation, on the stack in this case. The array value q[1][0] is being positioned right after q[0][columns-1]. The pointer implementation is allocating a disjoint block of memory for each row from the heap. By referencing beyond the end of the first row, you are in undefined behavior territory.
The stack based array is fully contiguous memory. Your heap based one is one allocation per row, plus an allocation to hold all those allocations. The memory for each allocation may be scattered throughout your heap in any order, with any amount of space between them. You cannot assume that adding offsets to the base of the first row's allocation is valid if you go past its end, and it's certainly a bug to try to reach a separate allocation by walking far enough off the end of a previous allocation.
If you want to do what you're trying, change your new[] expression to be flattened into a single array:
double * q = new [rows * columns];
Then you can index into it as if it is a 2d array.
Also, in your original post you use the wrong type of delete call on a, which is also an array and needs to be deleted as one (with [] after it.)

Flipping an array using pointers

#include <iostream>
using namespace std;
int* flipArray(int input[], int n)
{
int output[n];
int pos = 0;
for (int i = n-1; i >= 0; i--)
{
output[pos++] = input[i];
}
int* p = output;
for (int k = 0; k < n; k++)
cout << *p-k << endl << endl;
return p;
}
int main()
{
const int SIZE = 5;
int firstArray[SIZE];
for (int n = 0; n < SIZE; n++)
{
firstArray[n] = n+1;
}
int* a;
a = flipArray(firstArray, SIZE);
for (int j = 0; j < SIZE; j++)
cout << *a-j << endl;
cout << endl;
cout << *a << '\t' << *a+1 << '\t' << *a+2;
return 0;
}
I am attempting to flip firstArray using a function that returns a pointer, but I am struggling to understand how accessing an index using a pointer works.
Here is why I am confused:
Within the function flipArray, the following for-loop:
for (int k = 0; k < n; k++)
cout << *p-k << ' ';
prints "5 4 3 2 1" to the console. It was my understanding that I should be accessing an element of a vector with *(p+k), not *(p-k). If I print *(p+k), "5 6 7 8 9" is printed to the console. If I print the array without pointers and using k as the index location, "5 4 3 2 1" is printed to the console.
Within my main function, however, the values of *a which is assigned pointer p from the flipArray function, I do not get the same results:
for (int j = 0; j < SIZE; j++)
cout << *a-j << endl;
prints 5
0
-1
-2
-3 to the console, and
for (int j = 0; j < SIZE; j++)
cout << *a+j << endl;
prints 5
2
3
4
5 to the console.
Further, I thought that the pointer location of *p and the pointer of location of *a should be the same! But when I print the address &p in the function, I get the location of 0x28fde0, and when I print the address of &a in the main, I get the location 0x28fedc. Of course, these were done during the same run.
Could someone tell me where I have gone astray? Thanks!
Thanks to everyone for the informative answers.
I have updated my solution, and it is now returning what I would expect it to. I have a new question about memory leaks and when pointers need to be deleted.
int* flipArray(int input[], int n)
{
int* output = new int[n];
int pos = 0;
for (int i = n-1; i >= 0; i--)
output[pos++] = input[i];
return output;
}
int main()
{
const int SIZE = 5;
int firstArray[SIZE];
for (int n = 0; n < SIZE; n++)
{
firstArray[n] = n+1;
}
int* a;
a = flipArray(firstArray, SIZE);
for (int j = 0; j < SIZE; j++)
cout << a[j] << " "; // can also be written as *(a+j), which is more prone to bugs
delete [] a;
return 0;
}
Will the pointer output be deleted when the function flipArray returns? If not, how should I delete output while also returning it? Is deleting the pointer a in my main function the same thing as deleting output, because they point to the same location?
It has been pointed out that your main problem is coming from the operator precedence. The * operator in *p - k is evaluated before the -. This means that k will be subtracted from the value of the int pointed at by p.
This is a huge pain, which is why the braces pointer[k] are commonly used. There are situations where using pointer arithmetic *(pointer + k) makes more sense, but it can be a source of bugs.
One point to note here: it is always better to use parenthesis even if you are not sure whether or not you need them.
You do have a second problem:
Here you are declaring output on the stack as a local variable, then you are returning output. When you return back to the previous stack frame, this pointer will be pointing to a decallocated buffer:
int* flipArray(int input[], int n)
{
int output[n]; // allocated on the stack
int pos = 0;
for (int i = n-1; i >= 0; i--)
{
output[pos++] = input[i];
}
int* p = output;
for (int k = 0; k < n; k++)
cout << *p-k << endl << endl;
return p; // this stack frame ends.
}
This means the contents of the buffer can be overwritten if the space the buffer is using is reallocated. Use new to allocate on the heap:
int* output = new int[n];
make sure to call delete on the pointer when you are done using it.
This bug can even present security vulnerabilities in your applications, so make sure you know when to allocate on the heap in C++.
Update:
Question: When this function returns, the array still exists in memory, and it's location is stored in the pointer a. Does returning the value output delete it? If not, will deleting the pointer a when I am done with it in the main function serve the same purpose?
When you delete the pointer, the memory pointed to that pointer is deallocated and the pointer is left dangling. A reference to a deleted pointer is pointing at memory that is technically free, which is bad. If the allocator library decides that it wants to reuse that space, your buffer, which is now in free space, will be reallocated. This means your buffer will lose all data integrity and the data inside of it cannot be trusted.
A common practice is to assign pointers to NULL when you are done using them. This way your program will crash and you will know where your bug is:
int* p = new int[10];
...
delete p;
p = NULL;
...
p[0] = 0; // this will now crash because you are accessing NULL.
for (int k = 0; k < n; k++)
cout << *p-k ;
It was my understanding that I should be accessing an element of a vector with *(p+k), not *(p-k).
Your understanding is right.You are not accessing the array here.p points to the first element 5 and every time k is substracted from it, which gives you 5-0 5-1 5-2 and so on which is equivalent to the filpped array.So if you want to access the array using the pointer
for (int k = 0; k < n; k++)
cout << *(p+k) ;// Note the paranthesis
for (int k = 0; k < n; k++)
cout << *p-k << endl << endl;
What this code is doing is completely different from what you think it does.
*p - k will be processed like
*p = 5 - 0 = 5
*p = 5 - 1 = 4
and so on not *(p+k) or *(p-k)
For your understanding :
int a[5] = { 1,2,6,4,5};
In order to access 3rd element in the array you do
a[2] = *(a+2)
and not
*a + 2
*(a + 2) = 6 and *a + 2 = 1 + 2 = 3
Take care of not returning the pointer to the local variable which will lead to undefined behavior

2D dynamic memory allocation array in C++

A few days ago I learned about creating 2D allocated memory arrays from the internet, it works perfect. To access the array we just simply use matrix[i][j], however is there any way that I can dereference this 2D array by using * notation instead of [] for input as well as other methods?
First questions is solved I can use *(*(matrix + i) + j)
Now I got another question, last code segment is to free the allocated memory (I got it from internet as well), but I don't understand it, why cant I just use delete [] matrix ?
int **matrix;
// dynamically allocate an array
matrix = new int *[row];
for (int count = 0; count < row; count++)
{
matrix[count] = new int[col];
}
// input element for matrix
cout << endl << "Now enter the element for the matrix...";
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
cout << endl << "Row " << (i+1) << " Col " << (j+1) << " :";
cin >> matrix[i][j]; // is there any equivalent declaration here?
}
}
// free dynamically allocated memory
for( int i = 0 ; i < *row ; i++ )
{
delete [] matrix[i] ;
}
delete [] matrix ;
Answering your second question: when you allocate a 2D array with the following code
// dynamically allocate an array
matrix = new int *[row];
for (int count = 0; count < row; count++)
matrix[count] = new int[col];
you are in fact allocating one array of pointers (your matrix variable, which is a double pointer) and "row" arrays of integers (each one representing one row in your matrix, of size "col"), which are matrix[0], matrix[1], etc. up to matrix[row-1].
Thus, when you want to free your matrix, you'll first need to free every single row (the arrays allocated within the loop), and then the array which held the rows. In your case, the code you use to free your matrix is partly wrong, and should be more like the following :
// free dynamically allocated memory
for( int i = 0 ; i < row ; i++ )
{
//first we delete each row
delete [] matrix[i] ;
}
//finally, we delete the array of pointers
delete [] matrix ;
The delete within the loop will free each row of your matrix, and the final delete will free the array of rows. In your code, you use delete row times on your double pointer (matrix), which makes no sense.
Finally, using a single delete on the double pointer is wrong, because it would end up in a memory leak as you aren't freeing the memory allocated for each row, only the pointers referring to it.
Since a[b] is just *(a + b) you can of course do this:
*(*(matrix + i) + j)
Anyway, those new allocations are error prone. If one of the nested news throws then you'll have a leak. Try using std::vector instead.
Something like this would work:
int **matrix;
// dynamically allocate an array
matrix = new (std::nothrow) int *[row];
if (matrix == NULL)
{
// handle the error
}
for (int count = 0; count < row; count++)
{
*(matrix + count) = new (std::nothrow) int[col];
if (matrix[count] == NULL)
{
// handle the error
}
}
cout << "\nNow enter the element for the matrix...";
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
cout << "\nRow " << (i+1) << " Col " << (j+1) << " :";
cin >> *(*(matrix + i) + j);
}
}
Yes, you use pointer addition, but you need to understand how the memory is laid out. Say x is a pointer to the first element of an array of ints, if you want to access x[2], you can use *(x+2). However, with matrices it can get quite confusing and you're a lot more likely to access wrong indices in your matrix if you do this, so I wouldn't advise it.
You could do *(*(matrix+i)+j). It should be equivalent to bracket notation. What is happening with both notations is simply pointer arithmetic.

C++ What's wrong with my array/loop?

I've just started learning C++ so I'm fairly sure the answer may be a simple one. As a test I'm just setting up an array and then wanting to print out the array by looping through it.
My code is below. It prints out my array as expected but then prints out a load of other numbers below it. What are these numbers and where are they coming from? I suspect that 'sizeof' isn't the best to use. All of the examples i've found are alot more complicated than I need. In any case I am interested to understand the extra numbers. Any insight available?
int age[4];
age[0]=23;
age[1]=34;
age[2]=65;
age[3]=74;
for (int i = 0; i <= sizeof(age); i++)
cout << age[i] << endl;
return 0;
...output:
23
34
65
74
4
2147307520
0
2293608
4198582
1
3084992
3085608
-1
2293592
1980179637
-725187705
-2
sizeof gives the size of an object in bytes. If the array elements are larger than one byte (as int usually is), the number will be larger than the array size.
One way to get the number of elements in an array is to divide by the size of an element:
for (size_t i = 0; i < sizeof(age)/sizeof(age[0]); i++)
std::cout << age[i] << '\n';
(note that you also need < rather than <=, or you'll still step off the end).
Another way is to pass a reference to the array to a function template, instantiated for the array size:
template <typename T, size_t size>
void print(T (&array)[size])
{
for (size_t i = 0; i < size; ++i)
std::cout << array[i] << '\n';
}
print(age);
Yet another way is to use a std::vector or std::array instead of a plain array:
std::array<int, 4> age;
age[0]=23;
age[1]=34;
age[2]=65;
age[3]=74;
for (size_t i = 0; i < age.size(); ++i)
std::cout << age[i] << '\n';
sizeof(age) == sizeof(int) * number_of_elements ==>
number_of_elements = sizeof(age) / sizeof(int)
Then your code becomes:
for (int i = 0; i < sizeof(age)/sizeof(age[0]); ++i)
cout << age[i] << endl;
In C++ you may write a function to calculate the size for you(doesn't work with dynamic arrays):
template <class T, std::size_t size>
std::size_t array_size( T(&arr)[size] )
{
return size;
}
If you are up to C++11, you could go with for-each loop:
for(int element : age){
....
}
Also, free-function form of std::begin and std::end can do the job:
for(auto b = std::begin(age); b != std::end(age); ++b){
....
}
Sould be i < 4 because sizeof(age) is 16 on a 32 bits machine.
sizeof(age) is the number of bytes of age, not the number of elements.
Divide it by the size of an element of age to get that:
for (int i = 0; i < sizeof(age) / sizeof(*age); i++)
cout << age[i] << endl;
Note: for dynamic arrays, you have to store the size of the array separately:
std::size_t size = 4; // size_t corresponds to maximum size an array can hold
int* age = new int[size];
for (int i = 0; i < size; i++)
cout << age[i] << endl;
The other numbers are garbage past the end of the array.
age[10] is undefined behavior, which is essentially garbage numbers.
Sizeof is age array is 16 bytes I.e. Sizeof(int) * 4. You need array length.
Since sizeof(age) returns 16, you have your 4 values plus 12 ones whose value comes from the memory that is right after your array. Values in those memory segment is random, depending on what has been stored there right before you launched your program. If you used a memory check tool, you would have had an error since this memory is probably not allocated for your program.
As the other ones said, you should probably giving the exact number of element in your array as an additional variable.
const int COUNT = 4;
int age[COUNT];
age[0]=23; age[1]=34; age[2]=65; age[3]=74;
for (int i = 0; i < COUNT; ++i)
{
cout << age[i] << endl;
}