I want to achieve the following behaviour:
The class DataSequence has a pointer that points to an array in the main function.
print the array when an object in initialised of the class DataSequence
create a deep-copy of the same object (via a copy constructor) and print it when the object is formed.
The code I have written is as follows:
#include<bits/stdc++.h>
using namespace std;
class DataSequence{
float *ptr;
int _size;
public:
DataSequence(float input[] , int size){
_size = size;
ptr = new float; ptr = input;
//print the array
cout << "Main constructor" << endl;
for(int i=0 ; i<_size; ++i){
cout << *(ptr+i) << " ";
// ++ptr;
}
}
//copy constructor
DataSequence(DataSequence &d){
_size = d._size;
ptr = new float; *ptr = *(d.ptr);
//print the array
cout << "copy constrructor" << endl;
for(int i=0 ; i<_size ; ++i){
cout << *(ptr+i) <<" ";
// ++ptr;
}
}
};
int32_t main(){
int size=4;
float input[size];
int bins;
input[0] = 3.4;
input[1] = 1.3;
input[2] = 2.51;
input[3] = 3.24;
DataSequence d(input , size);
cout << endl;
DataSequence d1 = d;
return 0;
}
The output is as follows
Main constructor
3.4 1.3 2.51 3.24
copy constrructor
3.4 2.42451e-038 -2.61739e-019 3.20687e-041
I am unable to figure out why I am getting garbage from the copy constructor, can someone help.
This statement:
ptr = new float;
only allocates a single float. That means in this loop:
for(int i=0 ; i<_size; ++i){
cout << *(ptr+i)
as soon as i is greater than 0, you dereference invalid memory, which is undefined behavior. This results in a program that can do anything, including producing the "garbage" output you see.
If you want to allocate an array, you need to do:
ptr = new float[_size];
and to delete it, you need to do:
delete [] ptr;
Note that even if you allocate memory correctly as shown above, you are not actually copying the data from the argument. Just setting pointers would do a shallow copy which is not what you want.
You can do a deep copy like this:
std::copy(d.ptr, d.ptr + _size, ptr);
Related
#include<iostream>
#include<array>
#include <algorithm>
using namespace std;
class Array{
//declaring a array
public: int a[4];
public: int num;
public:
Array() {
//initializing a array
a[0] = 1;
a[1] = 2;
a[2] = 3;
a[3] = 4;
}
Array(const Array &NewObj){
a = new int[4];
for (int i = 0; i < 4; i++)
a[i] = NewObj.a[i];
}
};
int main()
{
cout<<" DEEP COPY : \n";
cout<<"============ \n";
//creating first object
Array obj1;
//changing value of a array at index 3
obj1.a[3]=15;
//declaring second object which is mapped by object 1
Array obj2(obj1);
cout << "Object 1: \n";
//printing values of a array
for(int i=0;i < (sizeof(obj1.a) / sizeof(obj1.a[0])); i++){
cout<<obj1.a[i];
cout << "\n";
}
cout << "Object 2: \n";
for(int i=0;i < (sizeof(obj2.a) / sizeof(obj2.a[0]));i++){
cout<<obj2.a[i];
cout << "\n";
}
return 0;
}
when creating a deep copy of a variable :
a = new int[4];
I received the error: expression must be a modifiable lvalue at this line.
The primary program's purpose is to make a deep copy of an array.
I started by defining the class and declaring an array.
Then I wrote a constructor () { [native code] } that initialises an array.
Then I wrote a copy constructor () { [native code] } in which I built a new array in which the values could be saved, but it failed with an exception about editable values.
You can get rid of a = new int[4]. Think about why you don't need that line in the regular constructor. Do you actually need to be allocating more memory?
Hope my question isn't confusing. I'll explain that with code.
I'm learning constructor/desctructor and new/delete in C++. While comparing two piece of code, I'm thinking about where the object and it's members are allocated.
I got a little bit confused when I see the new in constructor and main, and delete in destructor and main:
In the first example, I think local object c is allocated in stack. And that means, members list pointer, two int values (size and capacity) are all in stack. The object also contains an array in size 10, however the array itself is allocated in heap since new is used. When the program ends, the local object c (including the pointer) will be freed automatically. And the array pointed by pointer list will be freed as well, by destructor. Is that correct?
#include <iostream>
#include <string>
using namespace std;
class Collector {
int * list;
int size;
int capacity;
public:
// Default constructor
Collector(){
// We must define the default values for the data members
list = nullptr;
size = 0;
capacity = 0;
}
// Parameterized constructor
Collector(int cap){
// The arguments are used as values
capacity = cap;
size = 0;
list = new int[capacity];
}
bool append(int v){
if (size < capacity) {
list [ size++ ] = v;
return true;
}
return false;
}
// A simple print function
void dump(){
for(int i = 0 ; i < size ; i++) {
cout << list[i] << " ";
}
cout << endl;
}
~Collector(){
cout << "Deleting the object " << endl;
if (size > 0)
delete[] list;
}
};
int main(){
Collector c(10);
for (int i = 0 ; i < 15 ; i++){
cout << c.append(i) << endl;
}
}
Now compared with the second example, object is created with new. So all members including pointer and two int values are all allocated from heap. The array itself is also in heap for the same reason as the first example. Before the program ends, there is a delete so the pointer and two int values are all freed. The array is also freed since the desctructor is called when delete command is issued. Is my understanding correct?
#include <iostream>
#include <string>
using namespace std;
class Collector {
int * list;
int size;
int capacity;
public:
// Default constructor
Collector(){
// We must define the default values for the data members
list = nullptr;
size = 0;
capacity = 0;
}
// Parameterized constructor
Collector(int cap){
// The arguments are used as values
capacity = cap;
size = 0;
list = new int[capacity];
}
bool append(int v){
if (size < capacity) {
list [ size++ ] = v;
return true;
}
return false;
}
// A simple print function
void dump(){
for(int i = 0 ; i < size ; i++) {
cout << list[i] << " ";
}
cout << endl;
}
~Collector(){
cout << "Deleting the object " << endl;
if (size > 0)
delete[] list;
}
};
int main(){
Collector *c;
c = new Collector(10);
for (int i = 0 ; i < 15 ; i++){
cout << c->append(i) << endl;
}
delete c;
cout << "Exiting program" << endl;
}
I am working on an assignment which must pass pointers for all function
parameters. No global variables are allowed except global constants.
I'm to create an array of "bids" in main and fill it with readBids() function. This works, but I am then supposed to pass it to a function to bubble sort it. My program breaks once my sortBids function is called. I'm learning pointers now and I can't see what I am doing wrong. The Call Stack gives Project4.exe!main()Line32, which points to sortBids(bidArray, numBids);
Any help and an explanation would be very appreciated.
#include <iostream>
#include <string>
using namespace std;
string* readProductName();
int* readNumBids();
double* readBids(string,int);
void sortBids(double*, int*);
void averageBid();
void maxBid();
void totalBid();
void printReport();
int main(){
string* productName;
int* numBids;
productName = readProductName();
numBids = readNumBids();
double* bidArray = readBids(*productName, *numBids);
sortBids(bidArray, numBids);
cout << *productName << " " << *numBids << endl;
for (int i = 0; i < *numBids; i++){
cout << bidArray[i] << endl;
}
system("PAUSE");
delete productName;
delete numBids;
delete bidArray;
return 0;
}
string* readProductName(){
string* productName = new string;
cout << "\n Please enter a product name\n";
cin >> *productName;
return productName;
}
int* readNumBids(){
int* numBids = new int;
cout << "\n Please enter the number of bids\n";
cin >> *numBids;
return numBids;
}
double* readBids(string productName, int numBids){
int* size = new int;
size = &numBids;
string* productNamePtr = new string;
productNamePtr = &productName;
double *bidArray;
bidArray = new double[*size];
cout << "\nHow many bids for the " << *productNamePtr << endl;
for (int i = 0; i < *size; i++){
cout << "Please enter bid #" << i + 1 << endl;
cin >> bidArray[i];
if (bidArray[i] <= 0){
cout << "\nPlease enter an amount larger than 0\n";
i--;
}
}
return bidArray;
}
void sortBids(double* array, int *size){
bool* swap = bool{ false };
double* temp = new double;
do
{
*swap = false;
for (int count = 0; count < *size - 1; count++)
{
if (array[count] > array[count + 1])
{
*temp = array[count];
array[count] = array[count + 1];
array[count + 1] = *temp;
*swap = true;
}
}
} while (*swap);
}
Problem:
You intialise swap to 0. As swap is a pointer to bool, you have a null pointer.
You later dereference this pointer without ever having it point to a valid bool object:
*swap = true;
Tha is UB and this is why you get an access violation !
Solution
Either you define this variable as plain object bool swap = false; and use swap everywhere. Or you initialize it correctly bool *swap = new bool{false}; and you use *swap everywhere.
Miscellaneous advice:
Attention: bidArray is allocated with new[], so you have to delete[] it or risk undefined behaviour !
In pointer definitions, take the habit of puting the star next to the variable and not to the type. Why ? Because optically it is confusing:
bool* a,b; // defines a pointer to bool a, but a PLAIN BOOL b !
bool *a,b; // invites otpically to right interpretation by human reader
I've deleted previous dynamic double "a" array and created a new same-named long int array. But code::blocks gives me an error: "a has a previous declaration as double a". Here is the program:
/*Write a C++ program that receives integer n and
creates a dynamic array a of n size
of doubles, then shows a
maximum number in array, then array a is
deleted, then again receives
integer n and creates a dynamic array
a of n size of long int, then shows minimum number
in array.*/
#include<iostream>
using namespace std;
int main(){
double temp;
int *n = new int;
cin >> *n;
double *a = new double[*n];
for (int i=0;i<*n;i++)
cin>>a[i];
for (int i = 0; i<*n; i++){
if (temp<a[i]){
temp=a[i];
}
}
cout << "Max. num in array: " << temp << endl;
delete[] a;
cin >> *n;
long int *a = new long int[*n];
for (int i=0;i<*n;i++)
cin>>a[i];
for (int i = 0; i<*n; i++){
if (temp>a[i]){
temp = a[i];
}
}
cout << "Min. num in array: " << temp << endl;
delete n;
delete []a;
}
You cannot re-define a variable that was previously defined in the same scope. Initially you have
double *a; // a is a pointer to double
then you try
long int *a; // a is a pointer to long int
It doesn't matter that you delete[] a;. The variable a continues to exist, it is of a pointer type. Of course its allocated memory is deleted, but still you cannot re-declare it.
The instructor probably meant
char* a;
a = new char[n*sizeof(double)];
//...
delete[] a;
a = new char[n*sizeof(long int)];
If you don't want a conflict and want to keep the pointer of type double* and long int* respectively, you can put the variable inside a scope, like
{
double *a = new double[n];
// ...
delete[] a;
} // end of scope, `a` ceases to exist
{ // new scope
long int *a = new long int[n];
// ...
delete[] a;
}
You can't redeclare it. As you have freed up the memory space. But consider this, you can again allocate memory to the double array
Check here Here
#include<iostream>
using namespace std;
int main()
{
int *a;
a = new int[3];
for (int i = 0; i < 3; i++)
{
a[i] = i * 2;
cout << a[i] << endl;
}
delete [] a;
a = new int[3];
for (int i = 0; i < 3; i++)
{
a[i] = i * 3;
cout << a[i] << endl;
}
delete [] a;
return 0;
}
variable "a" is declared as double at first in main function, and you can't use "a" for another variable's name in same scope.
I am a C++ newbie here. My assignment is to create a Vector class without using the Vector class that already exists. I am not sure if I have implemented the assignment operator correctly. If so, how can I use it in the main function?
# include <iostream>
# include <string.h>
using namespace std;
class Vector{
public:
unsigned int * p;
size_t size;
Vector(){ // Default contructor
cout << "The default contructor" << endl;
this -> size = 20; // initial value
this -> p = new unsigned int [size];
// trying to set every elements value to 0.
for(int i = 0; i < size; i++){
*(p+i) = 0;
}
}
Vector (const Vector & v){ // The copy contructor
cout << "The copy constructor" << endl;
this -> size = v.size;
p = new unsigned int[size];
for(int i = 0; i < size; i++){
*(p+i) = *(v.p + i);
}
}
Vector& operator = (const Vector & v){
cout << "The assignment operator" << endl;
this -> size = v.size;
p = new unsigned int[size];
for(int i = 0; i < size; i++){
*(p + i) = *(v.p + i);
}
//p = p - size; // placing back the pointer to the first element
//return *this; // not sure here
}
void print_values(){
for(int i = 0; i< size; i++){
cout << *(p + i) << " ";
}
cout << endl;
}
};
int main(){
Vector * v1 = new Vector();
(*v1).print_values();
Vector * v2; // this should call the assignment operator but......... how?
v2 = v1;
(*v2).print_values();
Vector v3(*v1);
v3.print_values();
}
Your line:
v2 = v1;
Won't call your assignment operator. It just assigns one pointer to another pointer. You need to make an assignment between objects for your operator to be used.
You want something like:
Vector v1;
v1.print_values();
Vector v2;
v2 = v1;
And so on. Your program has some memory leaks, too - watch out!
Editorial note: Why *(p+i) instead of p[i]? The latter is a lot easier to read.
You are assigning one pointer to another, not one class instance to another. In order to invoke your assignment operator, you need to have two class instances (you only have one) and then deference the pointers so you access those instances, eg:
int main(){
Vector * v1 = new Vector();
v1->print_values();
Vector * v2 = new Vector();
*v2 = *v1;
v2->print_values();
Vector v3(*v1);
v3.print_values();
delete v1;
delete v2;
}
Alternatively:
int main(){
Vector v1;
v1.print_values();
Vector v2;
v2 = v1;
v2.print_values();
Vector v3(v1);
v3.print_values();
}