Consider the following, you have two sets of arrays - one of which has some set of integers stored with values, you can put these in an array and cout the value in the array with ease. However when you have an array with empty integers within it - it does not seem to be able to "store" the values to the integer value - why?
Here is an example:
int empty1;
int empty2;
int contain1 = 100;
int contain2 = 200;
int container [2] = { contain1, contain2 };
int empty_container [2] = { empty1, empty2 };
int i = 0;
while ( i != 2 ) {
empty_container[i] = i;
cout << endl << "empty_container[i]: " << empty_container[i] << endl
<< "empty1: " << empty1 << endl << "empty2: " << empty2 << endl;
cout << "i: " << i << endl;
cout << "container[i]: " << container[i] << endl;
cout << "contain1: " << contain1 << endl;
cout << "contain2: " << contain2 << endl;
i++;
}
Output:
empty_container[i]: 0
empty1: 4197341
empty2: 0
i: 0
container[i]: 100
contain1: 100
contain2: 200
empty_container[i]: 1
empty1: 4197341
empty2: 0
i: 1
container[i]: 200
contain1: 100
contain2: 200
Notice how empty1 all of a sudden has the value "4197341" while empty2 is 0, what is going on here?
UPD(from comments):
I mean like declaring an integer before and then set it through an array - is this not possible with C++?
Since you have never initialized or assign values to empty1 and empty2. empty1 and empty2 do not have global or static storage, they will not be initialized implicitly. Both of them contain garbage values.
You have undefined behavior. You can see that this compiler gives you different results on values of empty1 and empty2: Local variable not initialized Demo
Always remember to initialize variables before using it.
EDIT:
I mean like declaring an integer before and then set it through an array - is this not possible with C++?
IMHO, you cannot do that. You can initialize array elements with given initialized variables. However, what you did:
int empty_container [2] = { empty1, empty2 };
will not assign values to empty1 and empty2 with values in that array since the array itself is not initialized.
However, you may try the following:
empty_container[2] = {10}; //initialize array at first
empty1 = empty_container[0];
empty2 = empty_container[1]; //this will give you empty1 10 and empty2 0
See another live demo here: Array and Variable initialization demo
In here
...
int i = 0;
while ( i != 2 ) {
empty_container[i] = i; // <- HERE
cout << endl << "empty_container[i]: " << empty_container[i] << endl
...
you must have assumed that doing empty_container[i] = i would also affect empty1 or empty2. It seems that your thinking it wrong.
In C++, doing int empty_container [2] = { empty1, empty2 }; copies the values of empty1 and empty2 into the respective elements of empty_container. This means that even if they have the same values, they do not refer to the same memory location.
In order to also modify empty1 and empty2 when you modify empty_container, you must modify empty_container and change it to an array of pointers, or some similar methods to refer to some object.
The code:
#include <iostream>
using namespace std;
int main() {
int empty1;
int empty2;
int contain1 = 100;
int contain2 = 200;
int container [2] = { contain1, contain2 };
int* empty_container [2] = { &empty1, &empty2 };
// ^ Notice this
int i = 0;
while ( i != 2 ) {
*(empty_container[i]) = i;
// ^ Also this
cout << endl << "empty_container[i]: " << empty_container[i] << endl
<< "empty1: " << empty1 << endl << "empty2: " << empty2 << endl;
cout << "i: " << i << endl;
cout << "container[i]: " << container[i] << endl;
cout << "contain1: " << contain1 << endl;
cout << "contain2: " << contain2 << endl;
i++;
}
}
Notice that empty1 becomes 0 in the first iteration, and empty2 becomes 1 in the second iteration.
Related
This question already has answers here:
Passing a 2D array to a C++ function
(18 answers)
Closed 4 years ago.
I know how to pass 1D array pointer to a function by the following code
void fiddleWithArray(int*);
int main(){
int list[10] = {1, 3, 5, 7, 9, 11, 13, 17};
cout << "List at 0 before being passed is... " << list[0][0] << endl;
cout << "List at 1 before being passed is... " << list[1][0] << endl;
fiddleWithArray(list);
cout << "List at 0 after being passed is... " << list[0][0] << endl;
cout << "List at 1 after being passed is... " << list[1][0] << endl;
}
void fiddleWithArray(int* input){
input[0] = 45;
input[1] = 18;
}
However, when I try to do something similar for a 2D array(as shown below) I get an error.
void fiddleWithArray (int** input);
int main ()
{
int list [10][2]={{1,3},{5,7},{9,11},{13,17},{7,4},{5,90},{9,1},{3,25}};
int ** pointer;
pointer=&list;
cout<< "List at 0 before being passed is ... "<< list[0][0]<< endl;
cout<< "List at 1 before being passed is ... "<< list[1][0]<< endl;
fiddleWithArray(pointer);
cout<< "List at 0 after being passed is ... "<< list[0][0]<< endl;
cout<< "List at 1 after being passed is ... "<< list[1][0]<< endl;
}
void fiddleWithArray(int** input)
{
cout << input [6][1]<< endl;
}
The compiler gives an error saying "error: cannot convert ‘int (*)[10][2]’ to ‘int**’ in assignment
pointer=&list;"
I am also open to alternate methods of passing a 2D array pointer to a function.
Keeping your data structure, if you want to pass list to fiddleWithArray you can declare it as
void fiddleWithArray (int input[][2]);
and then, in the main program, call it as
fiddleWithArray(list);
There is also another problem in your program: cout << list[0] does not work. If you want to print the contents of the array when the first index is fixed to 0 you would write something like
cout << list[0][0] << " " << list[0][1]
If you instead intended to write the array where the second index is fixed to 0 or 1, then, to keep things easily, you need a short loop like
for (unsigned int i = 0; i < 10; i++)
cout << list[i][0] << " ";
cout << endl;
Finally, instead of using int[][] you may want to use std::arrayintroduced in C++11.
void fiddleWithArray(int input[10][2])
{
cout << input[6][1] << endl;
}
int main()
{
int list[10][2] = {{1,3},{5,7},{9,11},{13,17},{7,4},{5,90},{9,1},{3,25}};
int (*pointer)[10][2];
pointer=&list;
cout << "List at 0 before being passed is ... "<< list[0][0]<< endl;
cout << "List at 1 before being passed is ... "<< list[1][0]<< endl;
fiddleWithArray(*pointer);
cout << "List at 0 after being passed is ... "<< list[0][0]<< endl;
cout << "List at 1 after being passed is ... "<< list[1][0]<< endl;
}
Will be better using std::array
Pretty new to C++ here and programming as a whole so please be patient and understanding that my explanations may not be on the mark. The assignment for my OOP class calls for the following:
Design an Inventory class that can hold information for an item in a retail store's inventory.
Required private member variables:
- item number
- quantity
- cost
Required public member functions
Default constructor - Sets all the member variables to 0
Constructor #2 - Accepts an item's number, quantity and cost as arguments. Calls other class functions to copy these values into the appropriate member variables.
They way I'm going about this is slightly different. Rather than 1 value I'm trying to initialize an array and store all the values enter by the user there. However it seems, once the user exits the member/class function the value is removed from the array.
Kind of at my wits end here so any info or recommendations would greatly help.
#include <iostream>
using namespace std;
class inventory
{
private:
int productNum[10];
int productCount[10];
double productPrice[10];
int inventoryFillLevel;
int userPNumber;
int userQuantity;
double userPrice;
public:
inventory()
{
int counter = 0;
userPNumber = 0;
userQuantity = 0;
userPrice = 0;
while (counter < 10)
{
productNum[counter] = 5;
productCount[counter] = 6;
productPrice[counter] = 7;
counter++;
}
}
inventory(int pNumber, int pCount, int pPrice)
{
cout << "Now we're in the 2nd constructor in the Class" << endl;
cout << "The 1st number entered by the user is: " << pNumber << endl;
cout << "The 2nd number entered by the user is: " << pCount << endl;
cout << "The 3rd number entered by the user is: " << pPrice << endl;
Input(pNumber);
}
void Input(int pNumber)
{
int counter = 0;
cout << "\nNow we're in the function as called by the Constructor." << endl;
cout << "The 1st number entered by the user is: " << pNumber << endl;
cout << "In the function the counter is: " << counter << endl;
cout << "The value in the array at " << counter << " is: " << productNum[counter] << endl;
cout << "Now we set that to the value entered by the user" << endl;
productNum[counter] = pNumber;
cout << "And now the value in the array is: " << productNum[counter] << endl;
}
void Show()
{
int counter = 0;
cout << "After entering the value, let's check what is stored in the array: ";
cout << productNum[counter] << endl;
}
};
int main()
{
int a=0;
int b=0;
int c=0;
inventory inv1;
cout << "1st User entered value" << endl;
cin >> a;
cout << "2nd User entered value" << endl;
cin >> b;
cout << "3rd User entered value" << endl;
cin >> c;
cout << "Now we call the 2nd constructor and pass the values to it" << endl;
inventory(a, b, c);
inv1.Show();
return 0;
}
Thanks again for any help with this.
You appear to be handling your class incorrectly. The line
inventory(a, b, c);
only creates a temporary instance of inventory that is gone essentially after the line finishes execution. So when you call inv1.Show() it's still using the values that are assigned in your default constructor when inv1 was declared. You should remove the current declaration of inv and change
inventory(a, b, c);
to
inventory inv1(a, b, c);
Value are not getting removed. There is small flaw in the code.
1)- You are making mistake while creating an object. You are calling Show method with object created by default constructor.
inventory inv1;
....
inv1.Show();
Change the declaration of inv1 to inventory inv1(a, b, c); and call then call show method.
Also inventory(a, b, c); will create new object and will not effect inv1.
2)- You are always storing values at index 0 of the member array.
As you are declaring int counter = 0 whenever you are calling any method/constructor.
Make int counter ; a class member.
class inventory
{
private:
int counter;
public:
inventory():counter(0){....}
....
};
It will count the items you already push in your inventory.
Though you will have to take care how many item you already pushed in.
Alternative approach can be you can use std::vector instead of int array .
I have a program with one structnamed sample, it contains 2 int members and one char *. when creating 2 objects called a and b, I try assign a new dynamic string to a with the pointer and then copy all the values to b. so b = a. But later on when try to make changes to a like this : a.ptr[1] = 'X'; the pointer in b also changes. I want to know why, and how can I solve this.
struct Sample{
int one;
int two;
char* sPtr = nullptr;
};
int _tmain(int argc, _TCHAR* argv[])
{
Sample a;
Sample b;
char *s = "Hello, World";
a.sPtr = new char[strlen(s) + 1];
strcpy_s(a.sPtr, strlen(s) + 1, s);
a.one = 1;
a.two = 2;
b.one = b.two = 9999;
b = a;
cout << "After assigning a to b:" << endl;
cout << "b=(" << b.one << "," << b.two << "," << b.sPtr << ")" << endl << endl;
a.sPtr[1] = 'X' ;
cout << "After changing sPtr[1] with 'x', b also changed value : " << endl;
cout << "a=(" << a.one << "," << a.two << "," << a.sPtr << ")" << endl;
cout << "b=(" << b.one << "," << b.two << "," << b.sPtr << ")" << endl;
cout << endl << "testing adresses for a and b: " << &a.sPtr << " & b is: " << &b.sPtr << endl;
return 0;
}
Your struct contains a char*. When you assign all values in a to b, the pointer is also copied.
This means that a and b now point to the same char array. Therefore changing a value in this char array changes it for both structs.
If you do not want this, make a new char array for b and use strcpy.
You are copying the pointer not the value. To solve this you could override your assignment operator in the structure:
struct Sample{
int one;
int two;
char* sPtr = nullptr;
Sample& operator=(const Sample& inputSample)
{
one = inputSample.one;
two = inputSample.two;
sPtr = new char[strlen(inputSample.sPtr) + 1];
strcpy (sPtr, inputSample.sPtr);
return *this;
}
};
I'm brushing up on some beginner's algorithms as I familiarize myself with C++. There are already some bugs I have no idea where to start fixing.
1) The following gives me seg faults around the time when the fib() function returns its results. EDIT: with inputs >= 9
#include <iostream>
using namespace std;
int fib(int n) {
int fibs[] = {1, 1}; // dynamic array
int i = 2; // start at 3rd element
while(i < n) {
fibs[i] = fibs[i-2] + fibs[i-1];
cout << "DEBUG: fibs[" << i << "] = " << fibs[i] << endl;
i = i+1;
}
cout << "about to return to main()" << endl;
return fibs[n-1];
}
int main() {
cout << "\n================= Hello cruel world =================" << endl;
cout << "Enter a number: ";
int x;
cin >> x;
cout << "fib(" << x << ") = " << fib(x) << endl;
cout << "================ Goodbye cruel world ================\n" << endl;
return 0;
}
Otherwise, the code works just fine, the numbers are found correctly. But 2) when I change the function to support long integers, it starts acting weird:
#include <iostream>
using namespace std;
long fib(int n) {
long fibs[] = {1L, 1L}; // dynamic array
int i = 2; // start at 3rd element
while(i < n) {
fibs[i] = fibs[i-2] + fibs[i-1];
cout << "DEBUG: fibs[" << i << "] = " << fibs[i] << endl;
i = i+1;
}
cout << "about to return to main()" << endl;
return fibs[n-1];
}
int main() {
cout << "\n================= Hello cruel world =================" << endl;
cout << "Enter a number: ";
int x;
cin >> x;
cout << "fib(" << x << ") = " << fib(x) << endl;
cout << "================ Goodbye cruel world ================\n" << endl;
return 0;
}
Output:
================= Hello cruel world =================
Enter a number: 7
DEBUG: fibs[2] = 2
DEBUG: fibs[0] = 1
DEBUG: fibs[1] = 30071067265
DEBUG: fibs[2] = 30071067266
DEBUG: fibs[14] = 0
about to return to main()
fib(7) = 140733637791872
================ Goodbye cruel world ================
It doesn't make any sense to me. Thanks for any help.
int fibs[] = {1, 1};
is equivalent to:
int fibs[2] = {1, 1};
In another word, the array fibs(in both programs) has only two elements, it's illegal to access fibs[n] if n is bigger than 1.
In
long fibs[] = {1L, 1L};
the [] does not mean "as big as it needs to be", it means "count the number of initializers". It's the same as
long fibs[2] = { 1L, 1L };
And the comment
// dynamic array
is just plain WRONG.
The other answers explain what's wrong. To fix it, you can declare fibs as a vector instead:
vector<int> fibs(n, 1);
which will construct a vector of n integers and initialize them all to 1. Replacing that single line of code should be all you need!
Yes it will fail because fibs[2] doesn't exist!
This is not dynamic array by any mean. Its array of 2 long
long fibs[] = {1L, 1L}; // dynamic array
This question already has answers here:
Pointer errors in the method of transmission(c++)
(4 answers)
Closed 8 years ago.
Question: I can't seem to set a pointer to an address that was created inside of a function. It always gets set to Null, how do I fix this?
Problem: I believe the problem is caused by the variable being created inside of another function. What's happening is that after the function executes, the pointer is set to NULL again.
Code:
void listAdd(int *list, int &length) {
int* tempList = new int[ length + 1 ];
for( int i = 0; i < length; i ++ )
{
(tempList)[ i ] = (list)[ i ];
}
cout << " Previous adress: " << hex << list << endl;
if ( list != NULL )
delete[] list;
list = new int[ length + 1 ];
cout << " New address: " << hex << list << endl << dec;
for( int i = 0; i < length; i ++ )
{
(list)[ i ] = (tempList)[ i ];
}
delete[] tempList;
cout << " Enter a number: ";
int stored = 0;
cin >> stored;
(list)[length -1] = stored;
length ++;
cout << " Length: " << length << "\n";
cout << " value at array point 0: " << (list)[length -1];
cout << "\n retry " << (list)[length-1] <<"\n";
cout << "\n \n \n This is pointing to 0x" << hex << list << '\n' << flush;
}
It seems you would like the changes to list to be valid after the function returned: since list is passed by value, the object manipulated inside the function happens to be a copy of the one you passed in. You probably either want to pass the object by reference, i.e.:
void listAdd(int*& list, int &length) {
// ...
}
... or return the result
int* listAdd(int* list, int& length) {
// ...
return list;
}
list = listAdd(list, length);
Well, realistically, you really really want to encapsulate the objects in a class or just use std::vector<int>.