Dynamic allocation in function C++ - c++

i have some trouble in dynamic allocation with 'new' and reference. Please see a simple code below.
#include<iostream>
using namespace std;
void allocer(int *pt, int *pt2);
int main()
{
int num = 3;
int num2 = 7;
int *pt=&num;
int *pt2 = &num2;
allocer(pt, pt2);
cout << "1. *pt= " << *pt << " *pt2= " << *pt2 << endl;
cout << "2. pt[0]= " << pt[0] << " pt[1]= " << pt[1] << endl;
}
void allocer(int *pt, int *pt2)
{
int temp;
temp = *pt;
pt = new int[2];
pt[0] = *pt2;
pt[1] = temp;
cout << "3. pt[0]= " << pt[0] << " pt[1]= " << pt[1] << endl;
}
What i want to do is to make the function 'allocer' get 2 arguments which are the int pointer and allocate memory on one of them. As you can see, *pt becomes an array to take 2 integers. Inside of the function it works well which means the sentence that i marked 3. printed as what i intended. However, 1, 2 doesn't work. 1 prints the original datas(*pt= 3, *pt2= 7), 2 prints error(*pt= 3, *pt2= -81203841).
How to solve it?

You are passing in the pt and pt2 variables by value, so any new values that allocer assigns to them is kept local to allocer only and not reflected back to main.
To do what you are attempting, you need to pass pt by reference (int* &pt) or by pointer (int** pt) so that allocer can modify the variable in main that is being referred to.
Also, there is no good reason to pass pt2 as a pointer at all since allocer doesn't use it as a pointer, it only dereferences pt2 to get at the actual int, so you should just pass in the actual int by value instead.
Try something more like this:
#include <iostream>
using namespace std;
void allocer(int* &pt, int i2);
int main()
{
int num = 3;
int num2 = 7;
int *pt = &num;
int *pt2 = &num2;
allocer(pt, *pt2);
cout << "1. *pt= " << *pt << " *pt2= " << *pt2 << endl;
cout << "2. pt[0]= " << pt[0] << " pt[1]= " << pt[1] << endl;
delete[] pt;
return 0;
}
void allocer(int* &pt, int i2)
{
int temp = *pt;
pt = new int[2];
pt[0] = i2;
pt[1] = temp;
cout << "3. pt[0]= " << pt[0] << " pt[1]= " << pt[1] << endl;
}
Or
#include <iostream>
using namespace std;
void allocer(int** pt, int i2);
int main()
{
int num = 3;
int num2 = 7;
int *pt = &num;
int *pt2 = &num2;
allocer(&pt, *pt2);
cout << "1. *pt= " << *pt << " *pt2= " << *pt2 << endl;
cout << "2. pt[0]= " << pt[0] << " pt[1]= " << pt[1] << endl;
delete[] pt;
return 0;
}
void allocer(int** pt, int i2)
{
int temp = **pt;
*pt = new int[2];
(*pt)[0] = i2;
(*pt)[1] = temp;
cout << "3. pt[0]= " << (*pt)[0] << " pt[1]= " << (*pt)[1] << endl;
}

What you just did was that you dynamically allocated the pt that is inside the function. And this function variable pt is local and is not the same as the pt in the main function.
What you can do is, that you can pass the address of the pointer itself if you want to dynamically allocate memory to that pointer.

Related

C++ pointer referencing itself not producing expected output

I'm working with C++ pointers and I've encountered something curious.
If I reset a pointer to itself using "b = (int*)&b;", I expected the deferenced output to be the memory address of itself -- since it was pointing to itself.
So I thought *b would be "0x7ffea00819b0", but it's some strange numeric value.
But this isn't the case. The alternate value I get is confusing.
Here is my output:
Value of a = 10
Address of a = 0x7ffea00819ac
Value of b = 0x7ffea00819b0
Address of b = 0x7ffea00819b0
Dereference of b = -1610081872
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
int a = 10;
int *b = &a;
b = (int*)&b;
cout << "Value of a = " << a << endl;
cout << "Address of a = " << &a << endl << endl;
cout << "Value of b = " << b << endl;
cout << "Address of b = " << &b << endl;
cout << "Dereference of b = " << *b << endl;
}
Changing the type to unsigned long int fixed the issue.
Thank you all!
#include <iostream>
#include <type_traits>
using namespace std;
int main(int argc, char** argv)
{
unsigned long int a = 10;
unsigned long int *b = &a;
b = (unsigned long int*)&b;
cout << "Value of a = " << a << endl;
cout << "Address of a = " << &a << endl << endl;
cout << sizeof b << endl;
cout << sizeof *b << endl;
//static_assert(sizeof b == sizeof *b);
cout << "Value of b = " << b << endl;
cout << "Address of b = " << &b << endl;
cout << "Dereference of b = " << hex << "0x" << *b << endl;
}

Using pointers to duplicate and grow an existing array

I am failing to reach expected output when testing my 'grow'and 'subArray' functions. I've tried dereferencing back and forth in the function and also in main(). I'm wondering if there's something wrong with my memory allocation that is causing the lapse. I am extremely stuck and was hoping someone could potentially see something that I am missing, thanks.
#include <iostream>
#include <iomanip>
using namespace std;
bool isSorted(int *arr, int size){
for(int index = 0; index < size - 1; index ++){
if(*(arr + index) > *(arr + index + 1)){
return false;
}
}
return true;
}
double chain (int totalInches, int *feet, int *inches){
*feet = totalInches/12;
*inches = totalInches%12;
return *(feet)*3.49 + *(inches)*.30;
}
int *grow (int *arr, int size){
int *newArray;
newArray = new int[size*2]; //alocate new array
for(int i = 0; i < size*2; i+=2){
*(newArray + i) = *(arr+i);
*(newArray + i + 1) = *(arr+i);
}
return newArray;
}
int *duplicateArray (int *array, int size) {
int *newArray;
if (size <= 0)
return NULL;
newArray = new int [size]; //allocate new array
for (int index = 0; index < size; index++){
newArray[index] = array[index]; //copy to new array
}
return newArray;
}
int *subArray( int *array, int start, int length){
int *result = duplicateArray(array,5);
return result;
}
void showArray( int *arr, int size){
for(int i = 0; i < size; i ++)
{
cout << *(arr + i) << " ";
}
}
int main(){
int size = 8;
int testArray[] = {1,2,3,4,5,6,7,8};
cout << "testing isSorted: " << endl;
cout << "test data array 1: ";
showArray(testArray, size);
cout << endl;
cout << "Expected result: true" << endl;
cout << "Actual result: " << boolalpha << isSorted(testArray, size);
cout << endl;
int testArray2[]= {8,7,6,5,4,3,2,1};
cout << "test data array 2: ";
showArray(testArray2, size);
cout << endl;
cout << "Expected result: false" << endl;
cout << "Actual result: " << boolalpha << isSorted(testArray2, size);
cout << endl << endl << endl;
int chainTest = 53;
cout << "Checking chain for 53 inches: " << endl;
cout << "Expected result: 15.46 " << " " << "feet: 4 " <<
" " << "inches: 5"<< endl;
int in;
int ft;
cout << "Actual results : " << chain(chainTest,&ft,&in);
cout << " " << "feet: " << ft << " " << "inches: " << in << endl;
cout << endl << endl;
cout << "testing grow: " << endl;
cout << "test data 1: ";
showArray(testArray, size);
cout << endl;
cout << "Expected result: 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 " << endl;
cout << "Actual results: " << *(grow(testArray, size));
cout << endl << endl;
cout << "testing subArray:" << endl;
cout << "test data: ";
showArray(testArray, size);
cout << endl;
int start = 5;
int length = 3;
cout << "start: " << start << " " << "length: " << length << endl;
cout << "Expected result: " << "6 7 8" << endl;
cout << "Actual result: " << *(subArray(testArray, start, length));
cout << endl;
return 0;
}
Output:
As you notice, the loop is terminating after one traversal. The grow function is intended to duplicate and expand. In other words, it's supposed to make a copy of itself and append as it traverses. Any ideas as to why I am getting hung on the first element of the array?
You are actually doubling the array but only the first element is being printed because you are dereferencing an int* . To print all the elements, write a loop and print all the elements.
Also there is so much memory leak here. Please free memory after you are done using it. You are read about the delete[] operator.
Your loop going two at a time is good but it prevents you from selecting every element in the original array causing you to skip the even numbers. check your for loop and consider using two counters or if you want to modify your for loop to
for(int i = 0; i < size*2; i+=2){
*(newArray + i) = *(arr+i/2);
*(newArray + i + 1) = *(arr+i/2);
}
to ensure every element is reached
also as stated in the comments, use the showArray method you implemented
showArray(grow(testArray, size),size*2);

" invalid operands of types 'int' and 'int* const'" error from function, from book

I am going through the book "Beginning C++ Through Game Programming". I have typed this supplied script perfectly (I even pasted over it with the script supplied from online download- and used undo/redo to compare every character- to find no difference- except line endings and actually capitalizing the first character of function names). Despite no change, the supplied script compiles perfectly fine, but mine does not (unless I copy/paste supplied script). I am given the error in the second function: GoodSwap()
#include<iostream>
using namespace std;
void BadSwap(int x, int y);
void GoodSwap(int* const pX, int* const pY);
int main(){
int myScore = 150;
int yourScore = 1000;
cout << "Original Values" << endl;
cout << "myScore : " << myScore << endl;
cout << "yourScore: " << yourScore << endl;
cout << "Calling BadSwap()" << endl;
BadSwap(myScore, yourScore);
cout << "myScore : " << myScore << endl;
cout << "yourScore: " << yourScore << endl;
cout << "Calling GoodSwap()" << endl;
GoodSwap(&myScore, &yourScore);
cout << "myScore : " << myScore << endl;
cout << "yourScore: " << yourScore << endl;
return 0;
}
void BadSwap(int x, int y){
int temp = x;
x = y;
y = temp;
}
void GoodSwap(int* const pX, int* const pY){
int temp = *pX
*pX = *pY;
*pY = temp;
}
You missed a ; at first line of GoodSwap().
int temp = *pX // There should be a `;`
After this change, your program can compile in VS2015.

Explain C++ pointer initialization

int value = 3;
int *pValue1 = &value;
int *pValue2(pValue1);
cout << (*pValue1) << " " << (*pValue2);
In the above code if you have noticed I have written
int *pValue2(pValue1);
instead of
int *pValue2 = new int;
pValue2 = pValue1;
Still it is working and giving proper result.
Can any one explain to me which of the default function or constructor is getting called in this case?
int *pValue2(pValue1);
is equivalent to
int* pValue2 = pValue1;
Just assign to pValue2 pValue1 (assign to pValue2 address of variable value).
The difference should be apparent if you print the pointers themselves (the addresses) in addition to the values which they reference:
#include <iostream>
using namespace std;
int main() {
int value = 3;
int *pValue1 = &value;
int *pValue2(pValue1);
int *pValue3 = new int;
cout << pValue1 << " " << pValue2 << " " << pValue3 << endl;
cout << *pValue1 << " " << *pValue2 << " " << *pValue3 << endl;
pValue3 = pValue1;
cout << pValue1 << " " << pValue2 << " " << pValue3 << endl;
cout << *pValue1 << " " << *pValue2 << " " << *pValue3 << endl;
return 0;
}
You will also see that after new int, the memory pointed to by the pointer contains uninitialized data.

How to Access each element of a Structure with Pointer in C++

I am having problems with accessing individual structure elemnsts. How to output each structure element using pointer?
#include <iostream>
using namespace std;
struct student{
int rollno;
float marks;
char name[45];
};
int main(){
student s1[2]={{1,50.23,"abc"},{2,65.54,"def"}};
for(int j=0;j<2;j++){
cout<<"Output Rollno, Marks and Name Using Pointer"
}
return 0;
}
Just assign the address to a pointer, and print it.
student *ptr=s1; // or &s1[0], instead.
cout<<ptr->rollno;
You don't have a pointer.
To output the fields, you do what you'd do in any other situation, e.g.:
cout << "marks = " << s1[j] << "\n";
your loop should be something like:
for(int j=0;j<2;j++){
cout<<"Rollno:" << s1[j].rollno << " Marks:" << s1[j].marks << " Name:" << s1[j].name << endl;
}
or, using pointer (i.e. array + offset):
for(int j=0;j<2;j++){
cout<<"Rollno:" << (s1+j)->rollno << " Marks:" << (s1+j)->marks << " Name:" << (s1+j)->name << endl;
}
If you wanted to be real raw:
void* ptr = &s1[0];
for(int j=0;j<2;j++){
cout<< (int)*ptr << "," << (float)*(ptr+sizeof(int)) << "," << (char*)*(ptr+sizeof(int)+sizeof(float)) << endl;
}
char* p = (char* )s1;
for(int j=0;j<2;j++){
int* a = (int*) p;
cout << *a << " ";
a++;
float* b = (float*) a;
cout << *b << " ";
b++;
char* c = (char*) b;
cout << c << " ";
c = c + 45 + strlen(c);
cout<<endl;
p = c;
}