Declaring an array of pointers to objects dynamically in C++ - c++

I have to declare an array of pointers to objects (of classes) in C++. I thought this was the only way, but apparently I was wrong, as it throws a syntax error when I try to compile it. Specifically, among the 7 errors I received, 2 of these errors are in the lines: where I create the array using "new", and in the line where I call the "setData()" function. Can you tell me where I went wrong? Thanks.
#include <iostream>
class Test
{
public:
int x;
Test() { x=0; }
void setData(int n) { x=n; }
};
void main()
{
int n;
Test **a;
cin >> n;
a=new *Test[n];
for(int i=0; i<n; i++)
{
*(a+i)=new Test();
*(a+i)->setData(i*3);
}
}

Use a=new Test*[n];
Other than that, you have no delete´s in your program, trivial getter/setters
for public variables are strange, and *(a+i) could be a[i]

Your syntax is close but slightly off. Use this instead:
Test **a;
...
a=new Test*[n];
for(int i=0; i<n; i++)
{
a[i]=new Test();
a[i]->setData(i*3);
}
...
// don't forget to free the memory when finished...
for(int i=0; i<n; i++)
{
delete a[i];
}
delete[] a;
Since you are using C++, you should use std::vector instead. I would also suggest passing the desired value to the class constructor:
#include <iostream>
#include <vector>
class Test
{
public:
int x;
Test(int n = 0) : x(n) { }
Test(const Test &t) : x(t.x) { }
void setData(int n) { x=n; }
};
int main()
{
int n;
std::vector<Test> a;
cin >> n;
a.reserve(n);
for(int i=0; i<n; i++)
{
a.push_back(Test(i*3));
}
...
// memory is freed automatically when finished...
return 0;
}

Related

How to make a class member big 2D C array properly?

I have a very simple piece of code:
#include <iostream>
#include <random>
using namespace std;
const int K=1;
const int N=1024*K;
const int M=1024;
class C {
public:
C(){
minstd_rand0 g(1);
for(int i=0; i<N; ++i) for(int j=0; j<M; ++j)
a[i][j]=generate_canonical<float, numeric_limits<float>::digits>(g);
}
private:
float a[N][M];
};
int main()
{
C c;
cout<<"size="<<N*M/(1<<20)<<endl;
return 0;
}
At K=1 the code works, but at K=2 immeadiately fails with a segmentation fault.
So, as I understand, there is some restriction on the amount of data an arbitrary class can contain (not more than this amount of MB). How to get to know this amount exactly?
In my work I deal with arrays similar to a, which stand for the probability function distribution on some line segment. I have dozens of such arrays. I supposed to put all these arrays in 1 manager class that will handle all of them, but as this example shows, it is impossible, a segmentation fault occurs. So, I have for example 10 arrays (I would like to incapsulate all of them inside some single object) of double's with the number of elements 2x1024x1024. How to manage them in the program properly?
P. S. If to allocate them on the heap:
class C {
public:
C(){
p = new float*[N];
for(int i=0; i<N; ++i) p[i]=new float[M];
minstd_rand0 g(1);
for(int i=0; i<N; ++i) for(int j=0; j<M; ++j)
p[i][j]=generate_canonical<float,
numeric_limits<float>::digits>(g);
}
~C(){
for(int i=0; i<N; ++i) delete [] p[i];
delete [] p;
}
private:
float ** p;
};
the program works even at K=100. Is it a proper way to manage them?
After all, is there a way to allocate the array statically without making it a static class member?
P. P. S.
This piece of code works:
const int K=10;
const int N=1024*K;
const int M=1024;
float a[N][M];
class C {
public:
C(){
p=(float *)a;
minstd_rand0 g(1);
for(int i=0; i<N; ++i) for(int j=0; j<M; ++j)
p[i*M+j]=generate_canonical<float,
numeric_limits<float>::digits>
(g);
}
public:
float *p;
};
But I don't know if it is a proper way to hande such big arrays.

How to copy char array of a structure into another char array of a structure?

#include <iostream>
using namespace std;
struct stud
{
char name[10];
int id;
};
int input(stud a[], int size)
{
for(int i=1; i<=size; i++)
{
cout<<"name = ";
cin>>a[i].name;
cout<<"id = ";
cin>>a[i].id;
}
cout<<endl;
return 0;
}
int output(stud a[], int size)
{
for(int i=1; i<=size; i++)
{
cout<<"name = "<<a[i].name<<" ";
cout<<"id = "<<a[i].id<<" ";
}
cout<<endl;
return 0;
}
int copy(stud a[], stud x[], int size)
{
for(int i=1; i<=size; i++)
{
x[i].name=a[i].name;
x[i].id=a[i].id;
}
output(x,size);
cout<<endl;
return 0;
}
int main()
{
struct stud s[3], x[3];
input(s,3);
output(s,3);
copy(s,x,3);
return 0;
}
In this program the statement in function copy x[i].name =a[i].name; is not copying contents from 1 structure object to another. I have tried to put this statement in for loop for(int j=1;j<=10;j++) x[i].name[j] =a[i].name[j]; but still not working.
please suggest what should be changed or some alternatives for this.
i'll be very thankful to you for this.
regards,
umar
Either using a loop to copy each character in the name field or using thestrcpy function from <cstring> header works.
int copy(stud a[], stud x[], int size) {
for(int i = 1; i <= size; i++) {
// for(unsigned j = 0; j < 10; j++) {
// x[i].name[j] = a[i].name[j];
// }
strcpy(x[i].name, a[i].name);
x[i].id = a[i].id;
}
output(x, size);
cout << endl;
return 0;
}
But since you tagged this as c++, consider using std::string instead of a char array, unless you have a particular reason for using a char array. In that case x[i].name = a[i].name would have worked just fine and you could also use the standard algorithm library for copy. Also, using std::array instead of a raw C array for you "array of structures" might be a better option (does not degenerate into a pointer like a regular C array does).
Evrey single one of your loops is wrong, because in C++ arrays start at zero. So not
for(int i=1; i<=size; i++)
instead
for(int i=0; i<size; i++)
You cannot copy arrays by writing a = b;. Since your arrays are really strings there's a built in function strcpy to copy strings.
strcpy(x[i].name, a[i].name);
If you use = to copy struct, the char array inside that struct will be copied. You don't need to do anything more.
#include <iostream>
using namespace std;
typedef struct{
char name[10];
} type_t;
int main() {
type_t a = {"hihi"};
type_t b;
b = a;
a.name[0] = 'a';
cout<<a.name<<endl;
cout<<b.name<<endl;
return 0;
}
output:
aihi
hihi
ideone: https://ideone.com/Zk5YFd

How to stop this memory leak

I am learning pointers in C++ and am working on the new and delete functionality .
I have a local function which allocates memory on the heap but because i am returning the 2d array that i have created , I dont understand how to plug this memory leak, any help would be appreciated
main.cpp
#include<iostream>
#include "integers.h"
using namespace std;
int main()
{
int i[]={1,2,3,4};
int n=sizeof(i)/sizeof(int);
cout<<n<<endl;
printint(genarr(i,n),n);
}
integers.cpp
#include<iostream>
using namespace std;
int** genarr(int* val,int n)
{
int i,j;
int **a=new int*[n];
for(i=0;i<n;i++)
a[i]=new int[n];
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(i==j)
a[i][j]=val[i];
return a; // The variable that will leak but because i am returning it , how do stop it
}
void printint(int** a,int n){
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
return ;
}
integers.h
int** genarr(int*val, int n);
void printint(int **a,int n);
compiled by
g++ main.cpp integers.cpp -o integers
I have heard about smart pointers and am planning to learn about them after this , but for now i want to know if there is way to fix this or should i just go for smart pointers ?
To fix the problem, you need to delete what you new'd.
Change the code in main to:
int **arr = genarr(i,n);
printint(arr,n);
// we're done using arr; now we need to free it
for(int j=0;j<n;j++)
delete[] arr[j];
delete[] arr;
You can also extend integers.cpp and add a delarr function that complements genarr:
void delarr(int **a, int n) {
for (int i = 0; i < n; i++) {
delete[] a[i];
}
delete[] a;
}
Then main becomes simply:
int **arr = genarr(i,n);
printint(arr,n);
delarr(arr,n);
The easiest way to avoid memory leaks in C++ is to avoid explicitly calling delete anywhere. Smart pointers can solve this for you.
In your specific case, you could try something like this (untested):
using Vector = unique_ptr<int[]>;
using Matrix = unique_ptr<Vector[]>;
Matrix genarr(const int* val, int n)
{
Matrix a(new Vector[n]);
for(int i=0;i<n;i++)
a[i].reset(new int[n]);
// ...

Referencing Elements of Class Arrays using C++

I am trying to switch the elements of a class array using pointers. It is not outputting what I want. I tried using pointers in the function, but it's not allowed. It's also not allowed to call the function onto the class object without using a pointer, since I declared the class object using a double pointer. I am not using this method simply to solve a small problem, but just to practice using this method for more difficult problems.
Here is my code:
#include <iostream>
#include <algorithm>
using namespace std;
class thing{
public:
int index;
int value;
thing();
private: int number;
};
thing::thing()
{
number = 0;
}
void arrange(thing array[]){
for(int i=0; i<19; ++i){
if(array[i].value<array[i+1].value){
swap(array[i], array[i+1]);
arrange(array);
}
}
}
int main(){
thing** things = new thing*[20];
for (int i=0; i < 20; ++i)
{
things[i] = new thing(); // default constructor
things[i]->index = i;
things[i]->value=rand() % 100;
}
cout << "The random array is: " << endl;
for(int i=0;i<20;++i){
cout << things[i]->value << endl;
}
arrange(*things);
cout << "The arranged array is: " << endl;
for (int i=0; i < 20; ++i)
{
cout << things[i]->value << endl;
}
return 0;
}
When you call arrange(*things), you're just passing the first element of things to the function, not the array. It should be array(things). Then the arrange function should be written to use pointers:
void arrange(thing* array[]){
for(int i=0; i<19; ++i){
if(array[i]->value<array[i+1]->value){
swap(array[i], array[i+1]);
arrange(array);
}
}
}
Here you create an array of pointers to thing:
thing** things = new thing*[20];
Here you dereference it and get a pointer to thing which is stored at thing[0]:
arrange(*things);
But this function declaration
void arrange(thing array[])
treats this pointer as an array of thing, so that *things points to it first element, which is absolutely not what it really is.
You should change your arrange() function to use correct type:
void arrange(thing* array[]){
for(int i=0; i<19; ++i){
if(array[i]->value<array[i+1]->value){
swap(array[i], array[i+1]);
arrange(array);
}
}
}
And call it as:
arrange(things);
Regarding using vectors, you don't need to use any pointers at all.
std::vector<thing> things(20);
for (int i=0; i < things.size(); ++i)
{
things[i].index = i;
things[i].value=rand() % 100;
}
arrange(things);
void arrange(std::vector<thing>& array){
for(int i=0; i + 1 < things.size(); ++i){
if(array[i].value<array[i+1].value){
swap(array[i], array[i+1]);
arrange(array);
}
}
}

dynamic allocation of int array in c++ and assigning value

I am new to c++ and i was trying to do folloing two things without help of std::vector( This was done earlier)
Define an array of integer and the size of array is not known to me.
Pass this array into another function and output all the values stored in array.
int _tmain()
{
int* a = NULL;
int n;
std::cin >> n;
a = new int[n];
for (int i=0; i<n; i++) {
a[i] = 0;
}
testFunction(a,n);
delete [] a;
a = NULL;
}
void testFunction( int x[], int n)
{
for(int i =0;i<n;++n)
{
std::cout<<x[i];
}
}
But i can see that its not allocating memory of 10 bytes and all the time a single memory is filled up with 0.
Can anyone please help me if i am lacking something ? Or is there any alternative way for this apart from vector.
Thanks in Advance
I modified with one thing as i realized that i put ++n instead of i
int _tmain()
{
int* a = NULL;
int n;
std::cin >> n;
a = new int[n];
for (int i=0; i<n; i++) {
a[i] = i;
}
testFunction(a,n);
delete [] a;
a = NULL;
}
void testFunction( int x[], int n)
{
for(int i =0;i<n;++i)
{
std::cout<<x[i];
}
}
I’m not sure I understand all yours problems but the typo
for(int i =0;i<n;++n) in testFunction led to a very long loop.
Write:
for(int i =0;i<n;++i)
this print yours n "0"