Memory Address showing? C++ - c++

Not really sure what's going on here, I'm using Clion as my IDE which I don't believe has anything to do with this but I figured I'd add that information. My confusion comes from a function that I wrote
int Arry()
{
int Mynumbers [5] = {10};
std::cout << Mynumbers;
}
something simple. It should be assigning 5 integers the value of 10. But when I print out Mynumbers I am shown the memory address. Why is this happening, I thought that was what calling pointers was for. Thank you for your time.
Sincerely,
Nicholas

It is a bit complicated, and there are a few issues at play:
std::cout (actually, std::ostream, of which std::cout is an instance, does not have an overload of operator<< that understands plain arrays. It does have overloads that understand pointers.
In C++ (and C) an array name can be used as an expression in a place where a pointer is needed. When there is no better option, the array name will decay to a pointer. That is what makes the following legal: int a[10] = {}; int* p = a;.
The overload that takes a pointer prints it as a hexadecimal address, unless the pointer is of type char* or const char* (or wchar versions), in which case it treats it as a null terminated string.
This is what is happening here: because there isn't an operator<< overload that matches the array, it decays to the overload taking a pointer. And as it isn't a character type pointer, you see the hexadecimal address. You are seeing the equivalent of cout << &MyNumbers[0];.

Some notes:
void Arry() // use void if nothing is being returned
{
int Mynumbers[5] = {10}; // first element is 10, the rest are 0
//std::cout << Mynumbers; // will print the first address because the array decays to a pointer which is then printed
for (auto i : Mynumbers) // range-for takes note of the size of the array (no decay)
std::cout << i << '\t';
}

In C++, you can think of an array as a pointer to a memory address (this isn't strictly true, and others can explain the subtle differences). When you are calling cout on your array name, you are asking for it's contents: the memory address.
If you wish to see what's in the array, you can use a simple for loop:
for (int i = 0; i < 5; i++)
std::cout << Mynumbers[i] << " ";

The value of Mynumbers is in fact the adress of the first element in the array.
try the following:
for(int i=0; i<5;i++) {
cout << Mynumbers[i];
}

Related

Use the new operator to allocate an array of integers using the parameter as the size of the array within a function

I've been stuck on this problem and I'm hoping someone can explain where I'm wrong on this. I'm working on an assignment where I need to:
1) Allocate an array that can contain 100 int values by calling allocIntArray and assign the returned pointer to ptr1.
2) Use the new operator to allocate an array of integers using the parameter as the size of the array.
3) Return the pointer that is returned by the new operator.
4) Print out the new array.
I'm trying to print out the array after passing the size I want through the function.
int main() {
int *ptr = NULL;
ptr1 = *allocIntArray(100);
cout << ptr1 << endl;
return 0;
}
//The function I want to call
int *allocIntArray(int size) {
int *newarr = nullptr;
newarr = new int[size];
return newarr;
}
However when I call the function, the output comes out as 00F011E8.
I'm currently trying to understand why this is the output and not the first value in the array. (Just the number 1)
I've been having a lot of trouble grasping pointers any help understanding would be greatly appreciated.
Thanks to everyone who took the time to respond.
From what I understand from assignment directions, I shouldn't need to use vectors. I'm trying to modify my current code to display the array output and this is what currently comes up when I run it.[enter image description hereMy current results
At first, if you're using C++, you should use std::vector/std::array. This avoids a huge amount of possible problems.
It would look like:
#include <iostream>
#include <vector>
int main()
{
// create array of size 10 and initialize it with 0's
std::vector<int> vec(10, 0);
// print array
for(auto a : vec)
std::cout << a << '\t';
std::cout << std::endl;
}
If it's some kind of exercise, you have done four big mistakes:
you dereference the returned pointer to the array. So you get the value of the first element in the array and not the array itself. Simply remove the *.
you print out the address of the first element of the array. To print the array, you have to iterate over each element of the array. This can be done in a for loop:
for(int i = 0; i < 10; ++i)
std::cout << ptr1[i] << '\t';
you want to print out the array uninitialized. In fact, you try to print out some random values which are there in the memory. At first, you have to assign the elements values.
you forget to delete the array by using
delete[] ptr1;
I just have to answer as you seem to be missing some important fundamentals. Either the instructor should be dismissed or you have not paid enough attention in the class. So...
ptr1 = *allocIntArray(100);
You could not have pasted code that compiles, ptr1 is not declared.
You need to understand what the * operator does. What ever value to the right of * must be a pointer. What a pointer is should be fundamental in your understanding. If you had:
int* ptr1 = *allocIntArray(100);
You should have gotten a compiler error, so you must have:
int ptr1;
Somewhere along the line. As allocIntArray(...) returns a pointer, then *allocIntArray(...) gives you an integer.
You would have wanted to:
int* ptr1 = allocIntArray(100);
To get a pointer to the new array. Then you:
std::cout << ptr1 << std::endl;
So, what is ptr1? If it is a pointer then all you are doing is printing the pointer value. Per your stated problem, I'd say ptr1 is in fact a pointer. std::cout has not facility to work with a pointer as you expect. At that, it would have no way of determining the size of your array.
You would want to (And it hurts my fingers to write like this):
for(size_t i= 0; i < 100; ++i)
std::cout << ptr1[i] <<" ";
But!!!
4) Print out the new array.
So what will it print? There was never an instruction to initialize the array. It will print out what ever garbage is sitting in the array when it was created.
Side note, that the instructor has you doing a:
using namespace std;
Says much, as he/she should never have allowed it.

Pointers for int and Arrays

Hello i'm a noob in programming, i have a small doubt regarding pointers
#include<iostream>
using namespace std;
int main()
{
int myAge = 16;
int* agePtr = &myAge;
cout << "address of pointer" << agePtr << "Data at memory address" << *agePtr << endl;
int badNums[5] = {4, 13, 14, 24, 34};
int* numArrayPtr = badNums;
cout<< "address" << numArrayPtr << "value" << *numArrayPtr << endl;
numArrayPtr++;
cout<< "address" << numArrayPtr << "value" << *numArrayPtr << endl;
return 0;
}
In the first case while pointing an integer i use &myAge where as in
the second case of incrementing Arrays if i use &badNums the compiler
is returning an error, but if i use badNums its compiling why should
we use badNums instead of &badNums in the second case?
how can I increment the value in integer using pointers?
Arrays implicitly decay to pointers, as per the rules of c++. There are many implicit conversions in c++, this is one of them. When assigning an array to a pointer, it provides you with a pointer to the first element in the array.
Taking the address of an array (&badNums) will yield a pointer to the array, not to the first element. Array pointers are slightly more complicated and encode the size of the array in the type. The correct type for that assignment would be int (*numArrayPtr)[5] = &badNums; where numArrayPtr is a pointer to an array of 5 ints.
To increment a value pointer to by a pointer, you must first dereference that pointer using operator * just like if you wanted to read from or write to that value. It would look like (*numArrayPtr)++;.
In the first case, using &myAge refers to the address of that integer value. The reason why you must use badNums instead of &badNums when doing assignment to the integer pointer is because badNums is already an integer pointer. Arrays implicitly decay into pointers, so using &badNums in that assignment would work if you were doing:
int **numArrayPtr = &badNums;
which is just a pointer to a pointer to the address of badNums. So,
int *numArrayPtr = badNums;
just means that we have a pointer to the address of badNums.
When we have an integer pointer like this, you can increment the value of each integer in the array by doing this:
for (int i = 0; i < 5; i++){
numArrayPtr[i]++;
}
or, we can do the same thing without using array notation:
for (int *i = numArrPtr; i != numArrPtr + 5; i++){
(*numArrPtr)++;
}
I hope that answers your questions fully.
I have a small doubt regarding pointers
Just like i in badnums[i] is an index within array badnums[], a pointer is an index to something stored in memory. Since any variable is stored in memory, you can access the contents of a variable with a pointer to whatever it contains (which is what languages implicitly do when using variables in your code).
The difference is that with pointers you must know the type of what the pointer designates, while an index uses the known type of the indexed elements of the variable it points to... because sooner than later you will iterate the contents of some known variable using a pointer.

What does the code "int nums[5]" do?

What does int nums[5]; do? When I pass nums to std::cout, it prints a memory address I think, but I don't understand what the code itself is actually doing when it runs.
int nums[5]; allocates memory for a static array of 5 int values.
When you then do std::cout << nums;, it is actually calling std::cout.operator<<(nums); While std::cout has many << operators defined for many different type types, it does not have an << operator that accepts an int[] array as input. What it does have is an << operator that accepts a const void* memory pointer as input. It prints the value of the memory address that the pointer is pointing at.
A static array can "decay" into a pointer, in this case to an int*.
What is array decaying?
Any type of pointer can be assigned to a void*. And any non-const variable can be assigned to a const variable of compatible type. That is why the compiler does not complain when you call std::cout << nums;. It is essentially acting similar to std::cout.operator<<((void*)(int*)nums); behind the scenes.
'nums' is an array that holds 5 int type datas.For Example:
int nums[5] = {1,2,3,4,5};
if you want to cout nums,you should write your code like this:
for(int index = 0; index < 5; index ++){
std::cout<<nums[index]<<std::endl;
}
but ,if you want cout it's memory address,you should write your code like this:
for(int index = 0; index < 5; index ++){
std::cout<<nums<<std::endl;
nums ++;
}

C++ Passing Static Array and Dynamic Array By Reference

To fully understand how pointers, values, and references work, I am making a basic C++ program that attempts to tamper with some static and dynamic arrays and understand exactly how they should be passed in.
First I generate a static array of 3 elements. I then pass it into a function that modifies all elements. I then pass it into another function with a slightly different signature, but can also alter the array's values.
Next I generate a dynamically sized array, pass it into a function by reference so that all of the values in this dynamically sized array can be altered.
The code is as follows:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
void changeIndexStaticArrayMethod1(int* stat);
void changeIndexStaticArrayMethod2(int (&stat)[3]);
void changeIndexDynamicArrayMethod1(int* dyn, int size);
int main() {
const int MAX = 3;
int arr[MAX] = { 1,2,3 };
changeIndexStaticArrayMethod1(arr);
cout << arr[0] << endl;
cout << arr[1] << endl;
cout << arr[2] << endl;
cout << endl;
changeIndexStaticArrayMethod2(arr);
cout << arr[0] << endl;
cout << arr[1] << endl;
cout << arr[2] << endl;
int SIZE;
cout << "Please choose a size for the array" << endl;
cin >> SIZE;
int *ne = new int[SIZE];
//Build array
for (int i = 0; i < SIZE; i++) {
ne[i] = i;
}
changeIndexDynamicArrayMethod1(ne, SIZE);
for (int i = 0; i < SIZE; i++) {
cout << "ne[" << i << "] = " << ne[i] << endl;
}
//To hang program
cin >> SIZE;
delete[] arr;
delete[] ne;
return 0;
}
void changeIndexStaticArrayMethod1(int* stat) {
stat[0] = 10;
stat[1] = 20;
stat[2] = 30;
}
void changeIndexStaticArrayMethod2(int (&stat)[3]) {
stat[0] = 40;
stat[1] = 50;
stat[2] = 60;
}
void changeIndexDynamicArrayMethod1(int* dyn, int size) {
for (int i = 0; i < size; i++) {
dyn[i] = i * 10;
}
}
All of the above code works how I want it to, I just have a few questions as to why (some of the methods of passing arrays by reference I have found on other SO questions).
In the changeIndexStaticArrayMethod1() and changeIndexDynamicArrayMethod1() functions, why are we able to use the dereference * operator for our array as reference? My knee jerk reaction is seeing that as practically passing the array in by values since it is the dereference operator. I know that with arrays, it is much different than using variables, but also, why will the following not work for single int variables:
void changeStaticNumber(int* num){
num = 100;
}
Obviously the above will work if we use &num and not int* num, and obviously I don't fully understand the relationship between pointers and arrays, but I cannot figure out why when we pass an array by reference, int* staticArray is ok.
Any explanation for these problems I am having would be much appreciated. Thanks.
why are we able to use the dereference * operator for our array as reference?
The * in C means many things. It can mean the unary indirection ("contents of") operator, it can mean the binary multiplication operator and it can mean a pointer declaration. The int* stat is a pointer declaration.
Since you aren't using the * to dereference the contents of the pointer inside that function, I'm not quite sure what you are asking.
When you take the array name of your array in main(), it "decays" into a pointer to the first element. So what those function do, is to take a pointer by value. If you dereference the pointer by typing *stat = something; you access the actual array in main.
Should you do something weird like changing the pointer itself, for example stat++;, then it will not affect the address used in main. You passed the pointer itself by value, so the pointer is a local copy.
My knee jerk reaction is seeing that as practically passing the array in by values since it is the dereference operator.
You can't really pass arrays by value in C or C++, without resorting to dirty tricks (storing them inside structs or classes). For example, had your function been written as void changeIndexStaticArrayMethod1(int stat[3]) it would still give you a pointer to the first element. It will not pass an array by value, as the syntax might trick you into believing.
why will the following not work for single int variables:
void changeStaticNumber(int* num){ num = 100; }
Because num is the pointer itself, not its contents. In order to write code like that, you could pass the variable by reference int& num. Behind the lines this is really the same thing as passing a pointer, just with simplified syntax.
To understand the relation between pointers and arrays better, start by reading this whole chapter: http://c-faq.com/aryptr/index.html (C and C++ are identical when it comes to pointers).
Let me see if I can take a stab at this.
Pointers are simply address holders. Once you do int * ptr = myarray; --- what you are in tern doing is storing the address of the pointer my array into ptr --- array names are actually pointers to the first memory location in the array. You can use pointer arithmetic to get at everything else for example myarray +1 will point you to the next location or myarray[1].
Passing by value is not very useful when you need to modify your array. Passing in by reference is essentially making a pointer to the array and passing that. Since arrays like vectors are contiguous blocks of memory you can index through them rather easily.
As far as your example goes void changeStaticNumber(int* num){ num = 100; } will not work because what you are attempting to do is store 100 into the pointer's address. If you deference num and make it void changeStaticNumber(int* num){ *num = 100; } it will work because you are actually going one step further and accessing the data that num is pointing to. When you use &num it is essentially the same thing - & just gives you the address of something.
For example if you want to point a pointer to an int what you would do is
int num = 5;
int *ptr = &num;
at this point in time ptr has the same address in num. To print out the data in num or that ptr is pointing to you need to dereference or go one step further as I like to tell myself and dereference to so cout << *ptr;
In both changeIndexStaticArrayMethod1 and changeIndexDynamicArrayMethod1 you are not passing an array there is no pass by reference (which only happens if the parameter type is a reference type -- i.e. with &). The parameter has type int * (pointer to int). You are passing a pointer to int by value. There is no "dereference operator" in either function.
ne is already an int *, so passing it is nothing special. arr is an int [3], an array, not a pointer. In C, when an array-of-T is used in a context that expects a pointer-to-T, it is implicitly converted (without you needing to do anything) to a pointer to its first element. So when you do, changeIndexStaticArrayMethod1(arr), the compiler gets a pointer to the first element of arr, and passes that to the function.
The [] operator works on pointers. a[i] is always guaranteed to be the same as *(a + i). Inside both the changeIndexStaticArrayMethod1 and changeIndexDynamicArrayMethod1 functions, [] is used to access subsequent elements using a pointer to the first element.

how does compiler do with array declaration

char c='c';
char *pc = &c;
char a[]="123456789";
char *p = &(a[1]);
cout <<"the size of the a: "<< sizeof (a)<< endl; //10
cout <<"the size of the p: "<< sizeof (p)<< endl; //4
cout << p[100] <<endl;//cross boundary intentionally
cout << pc[0];//c
cout << pc[1];
Compiler no longer treat the p as an array? how does compiler verify whether it is or not an Array? Is there any difference between p and pc ?
Thanks!!!!
Compiler no longer treat the p as an array?
It never treated it as an array, because it was not. It was always a pointer. Arrays are not pointers. Read this, accept it, embrace it! They sometimes decay into pointers (when passed as parameters), but they are not pointers.
Is there any difference between p and pc ?
Type-wise - no. There's a difference in that they point to different chars.
Also, pc[1] is undefined behavior. You only own the memory pc points to directly - i.e. a single byte that contains the character 'c'. Same goes for p[100].
The compiler treats as arrays only variables declared as arrays, i.e. with square brackets. Pointers are not arrays, though, although you can treat array names as if they were pointers for the purposes of constructing pointer expressions.
If you would like to use an array structure where the compiler checks the bounds of the array, you can use std::vector. For example
#include <vector>
int main()
{
int array[]={0,1,2,3,4,5};
std::vector<int> vec;
vec.assign(array, array+6);
for(unsigned int i=0; i<vec.size(); ++i)
{
std::cout << vec.at(i);
}
return 0;
}
Here, vec.at(i) checks the bounds of the vector. If you use vec[i], this is also valid but the compiler does not check the bounds. Hope that helps.
The compiler cannot and will not treat p as an array. p is just a pointer to a char to which any address can be assigned. Why would the compiler treat it as an array?