forgive me for asking such a simple question, but I couldn't connect the dots from previous answers on SO or other sites. I have read that arrays are passed by reference by default and elsewhere I have read that arrays decay to pointers when passed into functions. I am trying to pass an array to a function and modify it, but cannot reconcile the previous two statements. I am not sure whether I am passing in a pointer or reference to toBin and whether it even matters. The following code is my attempt at making changes to the b array in the toBin function.
When I print the modified array, I get a whole bunch of unexpected text much bigger than the original allocated array of size 11 eg 1000000000 submarine blahblahblah. My expected output is 1000000000.
void toBin(int x,char a[]){ //passed by reference by default
std::cout << a << std::endl;
for (int i=9;i>=0;i--){
if(pow(2,i)<=x){
x=x-pow(2,i);
a[9-i]='1'; //i-1 because char b[] is zero indexed
};
}
}
int main()
{
char c[]="submarine";
double combination = pow(2,sizeof(c)-1);
char b[11]={'0','0','0','0','0','0','0','0','0','0'};
toBin(512, b);
for (int i=0;i<combination;i++){
std::cout << *(b+i) << std::endl;
}
}
Basically you pass everything to the function well. Thing that broke your output it's loop itself.
double combination = pow(2,sizeof(c)-1);
...
for (int i=0;i<combination;i++){
std::cout << *(b+i) << std::endl;
}
Your combination variable can have value like 2^8. So you point by*(b+i) to the address going far beyond the allocated array. To repair it you need change your loop to that:
for (int i=0;i< sizeof(b);i++){
Related
So my C++ instructor told us in class that there was no function to determine an array size in C++ and I was not satisfied with that. I found a question here on stackoverflow that gave this bit of code (sizeof(array)/sizeof(*array)) and while I don't exactly understand it, I understand it takes the total amount of memory allocated to the array and divides it by what I assume is the default memory allocation of its data type...(???)
I decided I wanted to practice writing functions (I'm in CS 111 - Fundamentals 1) and write a function that returned the number of elements in any array I passed it. This is what I wrote:
#include <iostream>
using namespace std;
int length_of_array(int some_list[])
{
// This only returns the integer 1 for some reason
return (sizeof(some_list)/sizeof(*some_list));
}
int main()
{
// Declare and initialize an array with 15 elements
int num_list[] = {2,4,6,8,10,12,14,16,18,20,22,24,26,28,30};
//Outputs what I assume is the total size in bytes of the array
cout << sizeof(num_list) << endl;
//Outputs what I assume to be size of memory set aside for each in element in an array
cout << sizeof(*num_list) << endl;
//This extrapolates array's number of elements
cout << "This is the output from direct coding in the\nint main function:\n" <<
(sizeof(num_list)/sizeof(*num_list)) << endl;
//This function should return the value 15 but does not
int length = length_of_array(num_list);
cout << "This is the length of the array determined\n";
cout << "by the length_of_array function:\n" << length << endl;
return 0;
}
The function returns 1 no matter what I do. Would somebody please give me a C++ specific workaround and explanation of how it works?
Thank you.
The problem is here:
int length_of_array(int some_list[]);
Basically, whenever you pass an array as the argument of a function, no matter if you pass it like int arr[] or int arr[42], the array decays to a pointer (with ONE EXCEPTION, see below), so the signature above is equivalent to
int length_of_array(int* some_list);
So of course when doing sizeof(some_list)/sizeof(*some_list) you will get the ratio between the size of the pointer the array decayed to and the size of the type representing the first element. In your case, 1, as it looks like on your machine the size of a pointer is probably 4 bytes (32 bits), same as the size of an int.
So my C++ instructor told us in class that there was no function to determine an array size in C++ and I was not satisfied with that.
YOUR TEACHER IS WRONG! There is a way of passing an array by reference and getting its size:
template<size_t N>
int length_of_array(int (&arr)[N])
{
std::cout << N << std::endl; // WORKS!
return N;
}
As a beginner in C++, first thing I came accross for functions is that they use a copy of the argument, for example if we execute this :
void add (double x){
x=x+3;
}
int main(){
double x=2 ;
add(x) ;
}
Then x would actually be equal to 2, not 5. Later on, learning about pointers, I found the following :
void fill (int *t){
for (int j=0, j<10, j++){
t[j]=j;
}
int main(){
int* p;
p = new int[10];
fill(p);
}
Now if we print what p contains, we find that it's indeed filled by the integers. I have some trouble understanding why it does that as I feel like it should have been the same as the first function ?
Thanks.
The reason it isn't the same as the first function is because you are passing the pointer by value. This means that if you modify the actual pointer, e.g by assigning to it, then it would only be in that state inside the function. The value that the pointer points to is still the original value, which will get modified since both copied pointers point to that same original value (don't forget notation of the form a[i] is equivalent to *(a + i), which does a dereference and is modifying the pointed value, not the pointer itself).
A small example that illustrates this would be the following (not accounting for memory leaks):
#include <iostream>
int test(int* x)
{
int* y = new int{10};
x = y;
std::cout << "Inside function: " << *x << "\n";
}
int main()
{
int* t = new int{5};
std::cout << "Before function: " << *t << "\n";
test(t);
std::cout << "After function: " << *t << "\n";
}
In first example you are using ordinary variable. When passing normal variable to function, like this, the function creates its own copy of the variable (it has same value as it has when you passed it, but it was copied to different place in memory). That is standard behaviour.
In second example you are using pointer: we can say that it points to the place in memory, where values are stored. Few of the advantages of them:
1) If you want to spare memory, but need to use same value in different functions -> mostly appplies to bigger objects than double, like array in your example
2) If you need to change value of variable/array/object in different functions
But careful, in the second function you still created copy, but not of value, but pointer. So basically, the "new" pointer is different object, but it is pointing to the same place in memory, so when accessing the value (which you are doing with [j]), you are editing the same place in memory.
It is not that easy concept to grasp, especially with more dimentional arrays, but hope this helped a little. You can learn some more in tutorials or c++ docs, for example this is a good one: https://www.geeksforgeeks.org/pointers-in-c-and-c-set-1-introduction-arithmetic-and-array/
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];
}
So my C++ instructor told us in class that there was no function to determine an array size in C++ and I was not satisfied with that. I found a question here on stackoverflow that gave this bit of code (sizeof(array)/sizeof(*array)) and while I don't exactly understand it, I understand it takes the total amount of memory allocated to the array and divides it by what I assume is the default memory allocation of its data type...(???)
I decided I wanted to practice writing functions (I'm in CS 111 - Fundamentals 1) and write a function that returned the number of elements in any array I passed it. This is what I wrote:
#include <iostream>
using namespace std;
int length_of_array(int some_list[])
{
// This only returns the integer 1 for some reason
return (sizeof(some_list)/sizeof(*some_list));
}
int main()
{
// Declare and initialize an array with 15 elements
int num_list[] = {2,4,6,8,10,12,14,16,18,20,22,24,26,28,30};
//Outputs what I assume is the total size in bytes of the array
cout << sizeof(num_list) << endl;
//Outputs what I assume to be size of memory set aside for each in element in an array
cout << sizeof(*num_list) << endl;
//This extrapolates array's number of elements
cout << "This is the output from direct coding in the\nint main function:\n" <<
(sizeof(num_list)/sizeof(*num_list)) << endl;
//This function should return the value 15 but does not
int length = length_of_array(num_list);
cout << "This is the length of the array determined\n";
cout << "by the length_of_array function:\n" << length << endl;
return 0;
}
The function returns 1 no matter what I do. Would somebody please give me a C++ specific workaround and explanation of how it works?
Thank you.
The problem is here:
int length_of_array(int some_list[]);
Basically, whenever you pass an array as the argument of a function, no matter if you pass it like int arr[] or int arr[42], the array decays to a pointer (with ONE EXCEPTION, see below), so the signature above is equivalent to
int length_of_array(int* some_list);
So of course when doing sizeof(some_list)/sizeof(*some_list) you will get the ratio between the size of the pointer the array decayed to and the size of the type representing the first element. In your case, 1, as it looks like on your machine the size of a pointer is probably 4 bytes (32 bits), same as the size of an int.
So my C++ instructor told us in class that there was no function to determine an array size in C++ and I was not satisfied with that.
YOUR TEACHER IS WRONG! There is a way of passing an array by reference and getting its size:
template<size_t N>
int length_of_array(int (&arr)[N])
{
std::cout << N << std::endl; // WORKS!
return N;
}
I'm trying to create a programme which will place all of the real numbers in an array - with the ordering of the numbers taking place in a separate function - into descending order, and print them out.
The following is the programme as I have it so far, but there are 2 issues with it, according to the compiler:
(i) On line 22 ("return N[t];"), I get "error: invalid types 'double*[double]' for array subscript".
(ii) On line 28 ("cout << sort_array(Q[100]) << " " "), I get "error: cannot convert 'double' to 'double*' for argument '1' to 'double* sort_array(double*)'".
I'm not quite understanding why these two errors are coming up, but I would love some help in resolving them.
#include <iostream>
#include <cstdlib>
using namespace std;
double *sort_array (double *N) {
double t;
int size=100, a, b;
for (t=0; t<size; t++)
*N = rand()%250;
for (a=1; a<size; a++) {
for (b=size-1; b>=a; b--) {
if (N[b-1] < N[b]) {
t = N[b-1];
N[b-1] = N[b];
N[b] = t;
}
}
}
return N[t];
}
int main()
{
double Q[100];
cout << sort_array(Q[100]) << " ";
cout << endl;
return 0;
}
The problem is the sort_array(Q[100]) statement. This is telling the compiler to call sort_array with the 101st double in the Q array (which is actually out of bounds). You really wanted to just pass in Q instead of Q[100].
However, note that passing C-style arrays as double* for example loses the length information and is not canonical C++. Instead you can use vector to carry the array and size with it.
EDIT: And since you're modifying the data in-place there is no need for your function to return anything at all. Change it to void and just skip the return at the end. You'll then have to iterate over the vector/array to print out each of the elements. cout doesn't provide builtin capability to print aggregates.
Finally a book from The Definitive C++ Book Guide and List might help get you up to speed on C++ concepts.
The first error is because N[t] is a double (it means "The t'th element of N"), but your function returns a double*. Your function doesn't look like it should return anything, actually. It sorts the data pointed to by N, so there's no need to return anything. You should probably switch to a void return value.
The second error is because Q[100] is a double (it means "the 101th element of Q, which is an error anyway since the last element of Q is Q[99], as array indexes in C++ begin at 0, not 1), but your function expects a double. I assume that what you actually mean to do is:
sort_array(Q)
to pass the pointer to the first element directly.
Remember that when passing arrays around, you only need to pass the address of the arrays's first element. In this case, Q, which is equivalent to &Q[0] but is easier to write.