Pointers as member data fields in C++ structs - c++

#include <iostream>
using std::cout;
using std::cin;
void printArray(int A[], int size) {
for(int i = 0; i < size; i++) {
cout << A[i] << "\t";
}
cout << "\n";
}
struct Array {
int *A;
int size;
int length;
};
void display(Array *arr) {
for(int i = 0; i < arr->length; i++) {
cout << arr->A[i] << "\t";
}
cout << "\n";
}
void fillArray(Array *arr) {
for(int i = 0; i < arr->length; i++) {
cin >> arr->A[i];
}
}
void add(Array *arr, int x) {
if(arr->length < arr->size) {
arr->A[++arr->length] = x;
}
}
int main() {
Array arr;
cout << "arr.size before initializing: " << arr.size << "\n"; // gives a garbage value
cout << "Enter the size of the array: ";
cin >> arr.size;
cout << "Output of arr variable &arr: " << &arr << "\n";
arr.A = new int[arr.size];
cout << "arr.length before initializing: " << arr.length << "\n"; // gives garbage value
cout << "How many elements do you want to enter: ";
cin >> arr.length;
fillArray(&arr); //This is not pass by value but pass by reference because
display(&arr); // this function displays the values of arr
add(&arr, 15);
cout << "The length of the array after adding: " << arr.length << "\n";
display(&arr);
printArray(arr.A, arr.length);
}
The output of this program is like this:
$ ./array_adt
arr.size before initializing: -140717888
Enter the size of the array: 10
Output of arr variable &arr: 0x7ffe4e0ec040
arr.length before initializing: 21932
How many elements do you want to enter: 5
4 6 7 3 2
4 6 7 3 2
The length of the array after adding: 6
4 6 7 3 2 0
4 6 7 3 2 0
I am highly confused why the element 15 isn't added to the array of the struct (which is actually a pointer which is initialised to an array in the heap). If someone can throw light on this it would be great for a many people as well as for understanding c++ concepts in depth.
Thanks a lot.

arr->A[++arr->length] = x;
should be
arr->A[arr->length++] = x;
Array indexes start at zero in C++, so the first element past the end of an array arr of size N is arr[N]. In other words 15 did get added to the array, just not in the right place.
Also your code leaks memory because the array allocated in main is never deleted. Correctly allocating dynamic memory is a big (and very important) topic. Consult your favourite C++ book, in particular you should research the rule of three

Related

Creating Two Array of Pointers of Custom Objects that Contain the same object (same pointer) in corresponding indices

I am trying to create two arrays of objects such that if i change an element of an array, it should be reflected in the second array (basically two arrays of pointers of objects that have the same pointers in each corresponding index)
Here is the code:
#include <iostream>
using namespace std;
class A{
private:
int n;
public:
A(int num){
n = num;
}
void print(){
cout << n;
}
};
int main() {
A** a = new A*[5];
A** b = new A*[5];
for(int i=0; i< 5; i++){
int n;
cout << "Enter a number: ";
cin >> n;
A obj(n);
a[i] = &obj;
b[i] = &obj;
}
// all the elements of these arrays are the last number entered by user
for(int i=0; i< 5; i++){
a[i]->print();
cout << " ";
b[i]->print();
cout << endl;
}
// because they point to the same memory location
for(int i=0; i< 5; i++){
cout << a[i] << " " << b[i] << endl;
}
}
The output looks like:
Enter a number: 1
Enter a number: 2
Enter a number: 3
Enter a number: 4
Enter a number: 5
5 5
5 5
5 5
5 5
5 5
0x7fff6ee63530 0x7fff6ee63530
0x7fff6ee63530 0x7fff6ee63530
0x7fff6ee63530 0x7fff6ee63530
0x7fff6ee63530 0x7fff6ee63530
0x7fff6ee63530 0x7fff6ee63530
What output I want:
Enter a number: 1
Enter a number: 2
Enter a number: 3
Enter a number: 4
Enter a number: 5
1 1
2 2
3 3
4 4
5 5
some_memory_address_1 some_memory_address_1
some_memory_address_2 some_memory_address_2
some_memory_address_3 some_memory_address_3
some_memory_address_4 some_memory_address_4
some_memory_address_5 some_memory_address_5
I understand that this is the case because C++ uses the same memory location for n defined inside the for loop, but how can I avoid this and get the result that I want?
two arrays of objects such that if i change an element of an array, it should be reflected in the second array
You can create one actual array (the storage, array-owner) and use it through two array-references:
#include <iostream>
#include <span>
#include <vector>
struct A { int n; }; // your class, simplified for the example
int main() {
std::vector storage(5, A{}); // the array
std::span a{storage}, b{storage}; // the references to the array
a[0].n = 42; // mutate the array
std::cout << a[0].n << ' ' << b[0].n << '\n'; // observe the mutation via array references
std::cout << a[1].n << ' ' << b[1].n << '\n'; // untouched elements are untouched
}
The full code for your use-case (A is still simplified):
#include <iostream>
int main() {
struct { int n; } storage[5];
auto &a = storage, &b = storage;
for (auto& element: a) std::cout << "Enter a number: ", std::cin >> element.n;
for (std::size_t i{}; i < std::size(a); ++i) std::cout << a[i].n << ' ' << b[i].n << '\n';
for (std::size_t i{}; i < std::size(a); ++i) std::cout << &a[i].n << ' ' << &b[i].n << '\n';
}

Missing integer when printing out from array after certain length

I have the following code:
#include <iostream>
using namespace std;
int main()
{
int length = 0;
int arrA[length];
cout << "Enter the length : ";
cin >> length;
cout << "Enter " << length << " integers for array : ";
for(int i = 0; i < length; i++)
{
cin >> arrA[i];
}
cout << "Array A : ";
for(int i = 0; i < length; i++)
{
cout << arrA[i] << " ";
}
cout << endl;
}
The above require the user to input the length of array followed by the integers that will be store in array. It work but the printing of the array value is incorrect when I input length 8 and above.
Working
Enter the length : 7
Enter 7 integers for array : 7 6 5 4 3 2 1
Array A : 7 6 5 4 3 2 1
Not working
Enter the length : 8
Enter 8 integers for array : 8 7 6 5 4 3 2 1
Array A : 8
Could this be due to memory issue or something?
int length = 0;
int arrA[length];
This creates an array of size zero
cout << "Enter the length : ";
cin >> length;
This sets the length variable to a value entered by the user but doesn't change the size of arrA which has already been created.
You obviously think that when the length variable changes that the array arrA will change as well, but this is not true.
Because you are accessing elements of an array which has zero size the behaviour of your program is undefined.
In addition this whole approach is incorrect because
int length;
...
int arrA[length];
is not legal C++. Because length is a variable this is a variable length array or VLA. VLAs are legal in C but are not legal in C++.
The best way to write this code in C++ is to use a vector. A vector is the C++ improvement on a C array.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int length;
cout << "Enter the length : ";
cin >> length;
vector<int> arrA(length);
...
int length = 0;
int arrA[length];
This is not valid C++.
What you may want to do is:
int *arrA = new int[length];
after cin >> length.
You will have to free the pointer later with delete[] arrA;
It is not due to a memory issue. But because variable length arrays are not part of the C++ standard.
length is a variable length array.
Read more about variable length arrays
Here
Here is the code if you do not want to use a vector. I would suggest not to use this for multifarious reasons. But go ahead and knock yourself out.
#include <iostream>
using namespace std;
int main()
{
int length = 0;
int *arrA = new int [length];
cout << "Enter the length : ";
cin >> length;
cout << "Enter " << length << " integers for array : ";
for (int i = 0; i < length; i++)
{
cin >> arrA[i];
}
cout << "Array A : ";
for (int i = 0; i < length; i++)
{
cout << arrA[i] << " ";
}
delete[] arrA;
cout << endl;
return 0;
}

How do I change the size of an array and fill it with automated elements?

I have an array with set elements 1 - 10. I have decided the size of the array and I have decided the elements of the array. My question is, how do I create an array of size x and fill it with elements 1,2,3,4 . . .
//sets values of the array elements and print them.
cout << "Array should contain x integers set to 1,2,3" << endl;
// QUESTION: How can I change the size of the array and have
// have values automatically entered?
int array[] = { 1,2,3,4,5,6,7,8,9,10 };
for (int i = 0; i <= (sizeof(array) / sizeof(int)-1); ++i) {
// sizeof(array)/sizeof(int) = 36/4. ints are 4.
cout << "Element " << i << " = " << array[i] << endl;
}
cout << "The number of elements in the array is: "
<< sizeof(array) / sizeof(int) << endl;
cout << endl;
cout << endl;
you can use dynamic memory allocation approach for your array, there you can give as much size as you want. Thanks.
//Variable size of Array program to print Array elements
#include <iostream>
using namespace std;
int main()
{
cout << "Enter Array size x:" << endl;
int x = 0;
cin >> x;
int *ptrArray = new int[x];
//Inittialise Array
for (int i = 0; i < x; i++)
{
ptrArray[i] = i + 1;
}
//Print Array elemts
cout << "Array elements:";
for (int i = 0; i < x; i++)
{
cout << ptrArray[i] << endl;
}
delete[] ptrArray;
return 0;
}

Using pointer arithmetic to add the contents of two arrays and save to an empty array

So I have written a function that should simply add the values of each element stored in two separate arrays, and save them to a third array.
I don't understand what the issue is, I am simply adding together the value of the int stored at the location referenced by each of my pointers, and saving it to my third, empty, array.
My code compiles just fine, but when I loop to print the contents of my third array (which should contain the sum of the two previous arrays elements at their respective indexes) it just prints a bunch of memory addresses. What gives?
EDIT: I fixed my while loop to perform the arithmetic, and everything is working well. My working code is below. Hope it helps someone else.
#include<iostream>
#include<stdlib.h>
using namespace std;
void arrayAdd(int firstArray[], int secondArray[], int targetArray[], int size){
int *firstPtr = firstArray;
int *secondPtr = secondArray;
int *tragetPtr = targetArray;
while (firstPtr <= &firstArray[size - 1] ){
//add the first two array elements
*tragetPtr = (*firstPtr + *secondPtr);
// point to the next location
*firstPtr++;
*secondPtr++;
*tragetPtr++;
}
}
int main() {
int totalElements;
const size_t ARRAY_SIZE = 50;
int firstIntegerArray[ARRAY_SIZE];
int secondIntegerArray[ARRAY_SIZE];
int thirdIntegerArray[ARRAY_SIZE];
cout << "Please enter the total number of elements for your array: ";
cin >> totalElements;
for(int i = 0; i < totalElements; i++){
cout << "Please enter a value for the first array at index " << i << ": ";
cin >> firstIntegerArray[i];
}
for(int i = 0; i < totalElements; i++){
cout << "Please enter a value for the second array at index " << i << ": ";
cin >> secondIntegerArray[i];
}
//run our arrayAdd function
arrayAdd(firstIntegerArray, secondIntegerArray, thirdIntegerArray, totalElements);
cout << "The conents of your two arrays added together is; " << endl;
for(int i = 0; i < totalElements; i++){
cout << thirdIntegerArray[i] << ", ";
}
return 0;
}
A local array decays to a pointer when it is passed to a function, so you can't use sizeof on it anymore. Indeed this:
void arrayAdd(int firstArray[]) {
int *firstPtr = firstArray;
std::cout << "sizeof(firstArray) == " << sizeof(firstArray) << std::endl;
std::cout << "sizeof(firstPtr) == " << sizeof(firstPtr) << std::endl;
}
int main() {
int test[] = {1,2,3,4,5,6,7,8,9,0};
arrayAdd(test);
return 0;
}
Prints:
sizeof(firstArray) == 8
sizeof(firstPtr) == 8
on my 64 bit machine.
Casting int[] to int* doesn't change anything since it already became a pointer as an argument. You should pass the size of the array to the method or, since you are working with C++, use an std::array or std::vector which will just solve any problem.

C++ Populate new elements in a resized dynamic array

While ripping through my homework, I've run across a bug I can't figure out. I've read and played around it but I can't figure out what I'm doing wrong.
The user enters an int pointer array, then the code is supposed double the size of the array and populate the new elements with 0. The problem is that the new elements aren't 0. What am I doing wrong and what are these numbers being printed, addresses?
Output:
Enter array size: 3
Enter Element 0: 10
Enter Element 1: 11
Enter Element 2: 12
Entered Array:
Element 0/3 is 10
Element 1/3 is 11
Element 2/3 is 12
Resized Array:
Element 0/6 is 10
Element 1/6 is 11
Element 2/6 is 12
Element 3/6 is -33686019
Element 4/6 is 1196933248
Element 5/6 is 201354124
Press any key to continue . . .
Code:
#include <iostream>
#include <string>
using namespace std;
int *createArray(int size)
{
int *newArray;
newArray = new int[size];
for( int i = 0; i < size; i++){
cout << "Enter Element " << i << ": ";
cin >> newArray[i];
}
return newArray;
}
int *dblArraySize ( int *myArray, int& size)
{
int *newArray;
newArray = new int[size*2];
for (int i = 0; i < size; i++)
newArray[i] = myArray[i];
for (int i = size; i < size*2; i++){
newArray[i] = 0;
}
size = size*2;
return newArray;
}
void displayArray(int *anArray, int size, string msg)
{
cout <<endl << endl << msg;
for (int i = 0; i<size;i++){
cout << endl << "Element " << i << "/" << size << " is " << anArray[i];
}
}
int main ()
{
int size,
*mainArray;
cout << "Enter array size: ";
cin >> size;
mainArray = createArray(size);
displayArray(mainArray,size, "Entered Array:");
dblArraySize(mainArray,size);
displayArray(mainArray,size, "Resized Array:");
}
The problem is that you are returning the newArray from dblArraySize, but never using it. You never modify mainArray
dblArraySize(mainArray,size);
Should be:
mainArray = dblArraySize(mainArray,size);
Also note: You are forgetting to release the memory for the original array.