c++ question:After assigning value to a variable,the other variable changed - c++

Following codes are my own API for index prior queue.When I test insert function,I get wrong answer.Then I debug codes,I found that the value of array qp changed after executing sentence----item[k]=vwhich is in insert function.Why the value of array qp changed after assigning value to array item?
template <class T>
class IndexPriorQueue{
private:
int index;//the num of items
int size;//capacity
int* pq;//index binaryheap
int* qp;//qp[pq[i]]=pq[qp[i]]=i
T* item;//item array;
public:
IndexPriorQueue(int qsize){//constructor function
size=qsize;
index=0;
pq=new int(size+1);
qp=new int(size+1);
item=new T(size+1);
for(int i=0;i<size+1;i++)
qp[i]=-1;
}
void insert(int k,T v){
if(contain(k)){
cout<<"index is already in queue"<<endl;
return;
}
//cout<<"insert"<<endl;
item[k]=v;//debug,after excuting this sentence,the value of qp exchanged??
pq[++index]=k;
qp[k]=index;
swim(index);
}
bool contain(int k){
return qp[k]!=-1?1:0;
}
void swim(int j){
while(j>1){
if(item[pq[j/2]]<item[pq[j]]){
exch(j/2,j);
j=j/2;
}else{
break;
}
}
}
void exch(int m,int n){
int temp=pq[m];
pq[m]=pq[n];
pq[n]=temp;
qp[pq[m]]=m;
qp[pq[n]]=n;
}
void display(){
cout<<"item:";
for(int i=1;i<size+1;i++){
cout<<item[i]<<" ";
}
cout<<endl;
cout<<"pq:";
for(int i=1;i<size+1;i++){
cout<<pq[i]<<" ";
}
cout<<endl;
cout<<"qp:";
for(int i=1;i<size+1;i++){
cout<<qp[i]<<" ";
}
cout<<endl;
}
};
Following codes are main function
int main(){
cout<<"before insert:"<<endl;
IndexPriorQueue<char> ipq(10);
ipq.display();
ipq.insert(1,'a');
cout<<"after insert:"<<endl;
ipq.display();
return 0;
}

The problems is your allocations. Take for example
new T(size+1)
That allocates one object of type T and initializes it to the value size + 1 (i.e. it calls the T constructor with size + 1).
If you need to allocate an "array" you should use square brackets [] as in
new T[size+1]
That will allocate an array of size + 1 number of T objects.
A much better solution though, is to use std::vector instead of doing it all manually yourself.

Related

Program stopped working and giving garbage value C++

I'm making a program for Dynamic Array, Where I implemented three methods. push_back(arguments...),pop_back(arguments...) and printArray(arguments...).
But when I increase the size of the array it gives the garbage value at that index and if I run the code for more than 15 values it stop working.
#include<iostream>
using namespace std;
void push_back(unsigned int value,unsigned int *array,int &arraySize,int &totalArrayItems ){
if(arraySize>totalArrayItems){
array[totalArrayItems]=value;
totalArrayItems=totalArrayItems+1;
cout<<"Current size: "<<arraySize<<endl;
}
else if(arraySize==totalArrayItems){
cout<<"Adding the Size of Array... \n";
unsigned int *tempArray=new unsigned int[arraySize+5];//making new array as asked in requirements
for(int i=0;i<arraySize;i++){
tempArray[i]=array[i];
cout<<"Value in Temp : "<<tempArray[i]<<endl;
}
unsigned int *temp=array;
array=tempArray;
arraySize=arraySize+5;
cout<<"Saving "<<value<<" at Position: "<<totalArrayItems<<endl;
array[totalArrayItems]=value;//adding the new value
cout<<"Value in Temp "<<totalArrayItems<<" : "<<tempArray[totalArrayItems]<<endl;
totalArrayItems=totalArrayItems+1;
cout<<"Updated size: "<<arraySize<<"Current value: "<<value<<endl;
delete []temp;//delete old array
}
}
void pop_back(unsigned int *array,int &arraySize,int &totalArrayItems){
if(totalArrayItems>0){
totalArrayItems=totalArrayItems-1;
if(totalArrayItems<(arraySize-5)){
unsigned int *tempArray=new unsigned int[arraySize-5];
for(int i=0;i <= totalArrayItems;i++){
tempArray[i]=array[i];
}
unsigned int *temp=array;
array=tempArray;
delete[] temp;
arraySize=arraySize-5;
}
}
}
void printArray(unsigned int *array,int totalArrayItems){
for(int i=0;i<totalArrayItems;i++){
cout<<"Value at "<<i<<" : "<<array[i]<<endl;
}
}
unsigned int* array in push_back is a local variable. When you assign a new value to it (a new pointer to a new memory location), it doesn't update the value of array in whatever method you called it from.
Pass a pointer to int* instead: int**, if you want your reallocations to stick.

Can return two arrays in struct but not in class C++

I can return two arrays by 'struct' with below codes; but can't translate the code to "class". the "class" code and error areattached also.
please shed lights on it. I have to use "class" and mutiple arrays in my project.
1) with "struct"
struct strA{
int *p;
int *p1;
};
strA setValue(int n)
{
strA strB;
strB.p=new int[n];
strB.p1=new int[n];
for (int i=0; i<n;i++)
{
strB.p[i]=i;
strB.p1[i]=i*2;
}
return strB;
}
int main(){
const int N=3;
strA strC;
strC=setValue (5);
for (int i=0; i<N;i++)
{
cout<< strC.p[i]<<endl;
cout<< strC.p1[i]<<endl;
}
return 0;
}
with "class". it turned out "error C3867: 'strA::setValue': function call missing argument list; use '&strA::setValue' to create a pointer to member"
class strA{
public:
int *p;
int *p1;
public:
strA();
~strA(){delete p, delete p1;}
strA setValue(int n);
};
strA strA::setValue(int n)
{
strA strB;
strB.p=new int[n];
strB.p1=new int[n];
for(int i=0; i<n;i++)
{
strB.p[i]=i;
strB.p1[i]=i*2;
}
return strB;
}
int main(){
const int N=3;
strA strC;
strC.setValue (N);
for (int i=0; i<N;i++)
{
cout<< strC.setValue<<endl;
cout<< strC.p1[i]<<endl;
}
return 0;
}
I will first address the error you have mentioned. There are other issues with this code as well.
The error is because of this line in main:
cout<< strC.setValue<<endl;
setValue is a function and it has to be called with arguments like this:
strC.setValue(N);
Other issues:
You cannot use cout to print the object returned from setValue
unless you have overloaded the << operator for the class strA.
In the setValue function you have defined an object strB and you assign memory to its members. This memory is not freed. What you are freeing are the members of the object strC defined in main. Look at the destructor of strA and you will understand.
The main in the first ("struct") version of the code can be used in the second ("class") version because p and p1 are public.
First, As the answer of P.W. You will meet a compile error in this line
cout<< strC.setValue<<endl; because you forgot to pass argument for the function setValue(int n).
Second, it is not suitable idea to write setValue(int n) function as what you have written. I recommend to you to write the function as following:
void ::setValue(int n)
{
this->p=new int[n];
this->p1=new int[n];
for (int i=0; i<n;i++)
{
this->p[i]=i;
this->p1[i]=i*2;
}
}
I think you are newbie and you should read more about Object Oriented Programming.

Unable to access vector value by index

#include<iostream>
#include<vector>
using namespace std;
class Stack
{
public:
int top;
vector<int> v;
Stack(int size)
{
top=0;
cout<<"Enter the values"<<endl;
for(int i=0; i<size; i++)
{
int val;
cin>>val;
v.push_back(val);
top++;
}
}
void push(int val)
{
v.push_back(val);
top++;
}
int pop()
{
int x=v[top];
top--;
return x;
}
void disp()
{
for(int j=top; j<=0; j--)
cout<<v[j]<<' ';
}
};
int main()
{
Stack s(3);
int k=s.pop();
cout<<k;
return 0;
}
I am trying to learn the basics of OOP.
Here, my Stack constructor and push function are working fine, but there is a problem with the pop and disp functions.
I'm assuming that I am using an incorrect syntax to access the elements of a vector(maybe?). Can anyone tell me where I am going wrong?
Also, the value of k always comes out to be 0.
You can use the vector functions
int k = s.back();
s.pop_back();
cout << k;
more informationhttp://www.cplusplus.com/reference/vector/vector/back/
You have a off-by-one index error.
The way you have implemented your class, when there are N items in the stack, the value of top is N.
Hence, top is not a valid index to access the elements of v. You can use:
int pop()
{
int x=v[top-1];
top--;
return x;
}
or
int pop()
{
top--;
int x=v[top];
return x;
}
As some of the other answers say, you can use the built-in vector functions to do these things (see pop_back and back.
However, if you want to define your own, I would use the vector.at(index) function. Addressing the values with the index as you have works, but it doesn't do any bounds checking at() does. Which would solve your problem above where your index isn't correct for the zero-based indexing of a vector.

Adding something to a dynamic array

I want to add X to the end of my Array if the array is full I double the size but i'm having trouble inserting it into newArray after I get it into newArray I use pointers to switch dynamicArray to newArray.
#include <iostream>
using namespace std;
class IntegerDynamicArray {
public:
IntegerDynamicArray();
~IntegerDynamicArray();
int add(int x);
private:
int * dynamicArray;
int currentSize=maxSize;
int maxSize=4;
};``
IntegerDynamicArray::IntegerDynamicArray()
{
dynamicArray = new int [maxSize];
}
IntegerDynamicArray::~IntegerDynamicArray()
{
delete [] dynamicArray;
}
int IntegerDynamicArray::add(int x)
{
cout<<x<<endl;
if(dynamicArray[currentSize-1]!=0)
{
int * newArray;
newArray= new int[currentSize*2];
for(int i =0;i<currentSize;i++)
{
newArray[i]=dynamicArray[i];
newArray[currentSize]=x;
}
currentSize=currentSize*2;
dynamicArray = newArray;
}
else
{
int * newArray;
newArray= new int[currentSize];
for(int i =0;i<currentSize;i++)
{
newArray[i]=dynamicArray[i];
newArray[currentSize-1]=x;
}
dynamicArray = newArray;
}
return *dynamicArray;
}
int main() {
IntegerDynamicArray intDynArray;
while (1) {
char input;
cout << "Enter A for add or anything else to quit: ";
cin >> input;
if (input == 'A') {
cout << "Enter number to add: ";
int x;
cin >> x;
cout << intDynArray.add(x) << endl;
} else {
break;
}
}
}
There are several problems with your code. Because you didn't asked a dedicated question these are the main ones:
Your class lacks a variable containing the index of the last written (or next free) index of the array. Instead you (mis)use currentSize as such index variable.
On each call of add() you allocate a new array although it might not be full already.
As already mentioned in the comments you do not delete [] your old arrays after copying into the new one.
You use 0 as indicator that a slot in your array is empty, but you do not prevent adding 0 as regular element and you do not initialize your array to zero.
As Thomas Matthews pointed out:
You are leaking memory while calling add(int x). For each use of new, there should be a call for delete
Consider the following:
int n=10;
int* x= new int[n];
//assign some values
int* temp=new int[n*2]; //create new array
for(int i=0;i<n;i++)
temp[i]=x[i]; //assign values from x
delete[] x; //free memory
x=temp; //assign to x address of new array
Manual memory managment can be risky, so consider using std::vector in future

Passing array as parameter in C++ ERROR

I tried to "select sort" an array. But instead of displaying the original array with just a "for loop", to go beyond the normal way and implement the stuffs I learned I decided to pass the original array to a function called "org_array" and tried to invoke it in the "void main()". But got couple of errors. I can't figure out what's the error I made in passing the parameters. Help please?
Code:
#include<iostream>
#include<conio.h>
using namespace std;
extern int s;
void org_array(int arr[30],int y);
void main()
{
int i,n,j,pos,a[30];
cout<<"Enter n: "<<endl;
cin>>n;
cout<<"\nEnter array: "<<endl;
for(i=0;i<n;i++){
cin>>a[i];
}
cout<<"Orginal Array: ";
org_array(a[30],n);
/*for(i=0;i<n;i++){
cout<<a[i]<<" | ";
}*/
for(i=0;i<n-1;i++)
{
int small=a[i];
pos=i;
for(j=i+1;j<n;j++)
{
if(a[j]<small)
{
small=a[j];
pos=j;
}
}
int temp=a[i];
a[i]=a[pos];
a[pos]=temp;
}
cout<<"\tSorted Array: ";
for(i=0;i<n;i++){
cout<<a[i]<<" | ";
}
getch();
}
void org_array(int arr[30],int y){
for(s=0;s<y;s++)
{
cout<<" "<<arr[s];
}
}
org_array(a[30],n);
is incorrect. It should be:
org_array(a,n);
And main should return int as per ISO. Further your declarations and definitions respectively should be this way:
void org_array(int [],int); // declaration - removed 30 since we might want to pass an array of larger size
void org_array(int arr[],int y) //definition
{
for(int s=0;s<y;s++) // You did not declare s as int
{
cout<<" "<<arr[s];
}
}
Just a side note:
An lvalue [see question 2.5] of type array-of-T which appears in an expression decays (with three exceptions) into a pointer to its first element; the type of the resultant pointer is pointer-to-T because an array is not a "modifiable lvalue,"
(The exceptions are when the array is the operand of a sizeof or & operator, or is a literal string initializer for a character array.)
In your code:
cout<<"Orginal Array: ";
org_array(a[30],n);
Should pass just the name of array as argument. Arrays are passed as reference to address of block of memory. You are referring to a specific index in array in your call. http://www.cplusplus.com/doc/tutorial/arrays/
org_array(a,n);
In your code:
void org_array(int arr[30],int y){
for(s=0;s<y;s++)
{
cout<<" "<<arr[s];
}
}
for loop requires a type for variable s. I assume you want an integer.
for(int s=0; s<y; s++)
Your main function should also be of type int and return int value.