pointers to multidimensional arrays in class - c++

I tried to write a program but I get segmentation fault (core dumped) while running . When I put a defined array like array_2d[10][1] , the problem is solved but I need to do the memory allocation for my project. It is a simple version of my code:
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <string>
using namespace std;
class Exam
{
private:
double** array_2d;
unsigned int num;
unsigned int num1;
public:
Exam();
void memoryallocation();
void show();
};
Exam::Exam()
{
num=10;
num1=1;
}
void Exam::memoryallocation ()
{
double** array_2d = new double*[num];
for (unsigned int i = 0; i < num ;i++)
{
array_2d[i] = new double[num1];
}
}
void Exam::show ()
{
ifstream file;
file.open("fish.txt");
for (unsigned int i = 0; i < num; i++)
{
for (unsigned int j = 0; j < num1; j++)
{
file >> array_2d[i][j];
cout<<array_2d[i][j]<<" ";
}
cout<<endl;
}
file.close();
}
int main()
{
Exam E;
E.memoryallocation();
E.show();
return 0;
}

Inside the function Exam::memoryallocation (), you are declaring array_2d again.
void Exam::memoryallocation ()
{
array_2d = new double*[num]; //remove the redeclaration of array_2d
for (unsigned int i = 0; i < num ;i++)
{
array_2d[i] = new double[num1];
}
}

Related

sum of an array elements in cpp return wrong value

I tried to write a simple code to calculate an array elements' sum. every thing looks normal but the function return the sum value wrongly (it always multiply it by two). Although if I want just print the value, it works fine.
this is the code:
#include <iostream>
using namespace std;
void getElements(int[],int);
int sumOfElements(int[],int);
int number;
int sum=0;
int main()
{
int a[10];
getElements(a,5);
sumOfElements(a,5);
cout<<"The sum is "<<sumOfElements(a,5)<<endl;
return 0;
}
//Getting array's elements
void getElements(int numbers[],int size_)
{
for (int i=0; i<size_; i++)
{
cout<<"numbers["<<i<<"]: ";
cin>>number;
numbers[i]=number;
}
cout<<'\n';
}
//Calculation the sum of array's elements
int sumOfElements(int numbers[],int size_)
{
for(int i=0;i<size_;i++)
{
sum+=numbers[i];
}
cout<<sum<<endl;
return sum;
}
any idea? thank you in advance!
You defined int sum globally and were calling sumOfElementstwice, so sum contained twice what you expected.
Here is a modified version of your code that does what you want:
#include <iostream>
using namespace std;
void getElements(int[], int);
int sumOfElements(int[], int);
int main() {
int numbers[5];
getElements(numbers, 5);
cout << sumOfElements(numbers, 5);
return 0;
}
void getElements(int numbers[], int size) {
for (int i = 0; i < size; i++) {
cin >> numbers[i];
}
}
int sumOfElements(int numbers[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += numbers[i];
}
return sum;
}
Here is a modified and simpler version of your program:
#include <array>
#include <iostream>
#include <numeric>
using namespace std;
int main(){
const int num_elements_to_sum = 5;
array<int, num_elements_to_sum> elements;
for(int i=0; i<num_elements_to_sum; ++i){
cin>>elements[i];
}
int sum = accumulate(elements.begin(), elements.end(), 0);
cout<<"Sum: "<<sum<<endl;
return 0;
}
C++ has a dedicated fixed size array container, use this instead of C-style arrays. This then allows to use standard library algorithms instead of your own implementation (e.g. accumulate).

I cant seem to assign a pointer an array and then change the contents of the array

I couldn't figure out how to make a function return an array so instead I decided to try and pass an empty array (of the correct size) into my function and than reassign the address to a different array of the same size. Is this at all a way to do things??? Can someone show me what to do? if this is wrong can you fill me in on how to do this?
here is my code:
#include <iostream>
#include <cmath>
using namespace std;
void ArrayFiller(int earray,int s, int f){
int *ptrarray = &earray;
int prenum_size = std::abs(s) + f - 1;
int pre_num[prenum_size];
for(int x=s;x<f;x++){
pre_num[x+std::abs(s)] = x;
}
*ptrarray = pre_num;
}
int Main(){
int first = -10;
int second = 15;
int temp[abs(first) + abs(second)];
ArrayFiller(temp, first, second);
int n = sizeof(temp)/sizeof(temp[0]);
for (int i = 0; i < n; i++) {
cout << temp[i] << ' ';
}
return 0;
}
I think you're looking for something like this:
#include <iostream>
#include <cmath>
using namespace std;
void ArrayFiller(int earray[],int s, int f){
for(int x=s;x<f;x++){
earray[x+(std::abs(s))] = x;
}
}
int main(){
int first = -10;
int second = 15;
int n = abs(first)+abs(second);
int* temp = new int[n];
ArrayFiller(temp, first, second);
for (int i = 0; i < n; i++) {
cout << temp[i] << ' ';
}
delete [] temp;
return 0;
}

Getting the same string (gene array) in every object in the array dna (dynamically allocated)

I have created a class called DNA, having a no argument constructor and two member functions namely initialize() and show(). The problem is when I create an
array using new operator and call the initialize function on every object using a for loop, instead of getting different string in the member variable "genes", I am getting the exactly the same set of characters (array) in the genes in every object in the array. Although I seed the srand() function before initialization of the string, there is no effect seen of it.
The code below.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
string sampleSpace("ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz");
class DNA {
private:
int length;
char *genes;
public:
DNA() {
length = 0;
genes = new char[length];
}
void initialize(int len) {
srand(unsigned(time(NULL)));
this -> length = len;
delete genes;
this -> genes = new char[length];
for (int i = 0; i < length; i++) {
*(genes + i) = sampleSpace.at(rand() % sampleSpace.length());
}
}
void show() {
for (int i = 0; i < length; i++) {
cout<<*(genes + i);
}
cout<<endl;
}
};
int main() {
DNA *dna = new DNA[10];
DNA *temp = dna;
for (int i = 0; i < 10; i++) {
(*temp).initialize(10);
temp++;
}
temp = dna;
for (int i = 0; i < 10; i++) {
(*temp).show();
temp++;
}
return 0;
}
You should use the new random API and use a proper random engine:
class DNA {
private:
int length;
std::unique_ptr<char[]> genes;
static std::default_random_engine random;
public:
DNA() : length{0}, genes{} {}
void initialize(int len) {
this-> length = len;
this-> genes = std::make_unique<char[]>(length);
std::uniform_int_distribution<std::size_t> distribution{0, sampleSpace.size() - 1};
for (int i = 0; i < length; i++) {
genes[i] = sampleSpace.at(distribution(random));
}
}
void show() {
for (int i = 0; i < length; i++) {
cout<<genes[i];
}
cout<<endl;
}
};
This will initialize a std::default_random_engine and use a proper number distribution. Also, I changed the code for unique pointer.
Here's a live example.
To piggyback on the answer given, here is the equivalent answer, but using std::vector and std::generate:
#include <iostream>
#include <algorithm>
#include <ctime>
#include <string>
#include <vector>
#include <random>
std::string sampleSpace("ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz");
class DNA
{
private:
std::vector<char> genes;
public:
void initialize(int len)
{
static std::default_random_engine random;
genes.resize(len);
std::uniform_int_distribution<size_t> distribution{0, sampleSpace.length()-1};
sampleSpace.at(distribution(random));
std::generate(genes.begin(), genes.end(), [&] ()
{ return sampleSpace.at(distribution(random)); });
}
void show()
{
for (auto& v : genes)
std::cout << v;
std::cout << "\n";
}
};
int main()
{
DNA dna[10];
for (int i = 0; i < 10; i++)
dna[i].initialize(10);
for (int i = 0; i < 10; i++)
dna[i].show();
}
Live Example
Note that length is also no longer needed.

Passing an array as a parameter to a function

So I'm doing a programming assignment and I've ran into an issue, when every I attempt to pass the arrays to the header file, I receive an error while compiling, I'm not too clear as how to do this and would much appreciate so assistance in passing these arrays.
Here is the Header file "sorting.h"
#include <iostream>
#include <cstdlib>
using namespace std;
int cost = 0;
void bubble(int Ar[],int N)
{
cost=0;
int swaps = 1;
while(swaps)
{
swaps=0;
for(int i = 0;i<N;i++)
{
if(Ar[i]>Ar[i++])
{
swap(Ar[i],Ar[i++]);
swaps = 1;
cost += 6;
}
cost++;
}
}
for(int i=0;i<N;i++)
{
cout<<Ar[i]<<endl;
}
cout<<cost<<endl;
}
void shellSort(int Ar[], int N)
{
cost=0;
int swaps = 1;
int gap = N/2;
while(gap>0)
{
while(swaps)
{
swaps = 0;
for(int i = 0;i<N;i++)
{
if(Ar[i]>Ar[i+gap])
{
swap(Ar[i],Ar[i+gap]);
swaps = 1;
cost+=6;
}
cost++;
}
}
gap=gap/2;
}
for(int i = 0;i<N;i++)
{
cout<<Ar[i]<<endl;
}
cout<<cost<<endl;
}
void quickSort(int Ar[],int left, int right, int N)
{
cost = 0;
int i=left,j=right,tmp;
int pivot = Ar[(left+right)/2];
/*partition*/
while(i<=j)
{
while(Ar[i]<pivot)i++;
while(Ar[j]>pivot)j--;
if(i<=j)
{
tmp=Ar[i];
Ar[i]=Ar[j];
Ar[j]=tmp;
i++;
j--;
cost +=6;
}
cost+=1;
}
/* recursion*/
if(left<j)quickSort(Ar,left,j,N);
if(i<right)quickSort(Ar,i,right,N);
for(int i=0;i<N;i++)
{
cout<<Ar[i]<<endl;
}
cout<<cost<<endl;
}
/*#if _INCLUDE_LEVEL__<1
int main()
{
}
#endif*/
and here is the main file "sorting2.cpp"
#include <iostream>
#include <cstdlib>
#include "sorting.h"
using namespace std;
//void bubble();
//void shellSort();
//void quickSort();
int main()
{
int N = 20;
int Ar[N];
int Ar2[N];
for(int i = 0;i<N;i++)
{
Ar[i] = Ar2[i] = rand()%100;
}
bubble(Ar[],N);
for(int i = 0;i<N;i++)
{
Ar[i] = Ar2[i];
}
shellSort(Ar[],N);
for(int i = 0;i<N;i++)
{
Ar[i] = Ar2[i];
}
quickSort(Ar[],0,19,N);
}
Thanks in advance!
Change
bubble(Ar[],N);
to
bubble(Ar, N);
(and in other similar places as well)
There are also other problems in your code:
Variable-length arrays are not part of C++ standard:
int Ar[N];
int Ar2[N];
You should change int N = 20; to const int N = 20;
This line produces undefined behavior because the order of evaluation of operator arguments is unspecified:
if(Ar[i]>Ar[i++])

Pointer to vector

I've got this code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<string> *vecptr;
int veclen;
void getinput()
{
string temp;
for(int i = 0; i < 3; i++)
{
cin>>temp;
vecptr->push_back(temp);
}
veclen = vecptr->size();
}
int main()
{
getinput();
for(int i = 0; i < veclen; i++)
{
cout<<vecptr[i]<<endl;
}
return 0;
}
My compiler(G++) throw me some errors: test2.cpp:28:17: error: no match for 'operator<<' in 'std::cout << *(vecptr + ((unsigned int)(((unsigned int)i) * 12u)))' ...
What's wrong? What can I do to fix it?
The program is still not completely right. You have to initialize the vector pointer and then give it a size and the use it. A full working code could be,
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<string> *vecptr = new vector<string>(10);
int veclen;
void getinput()
{
string temp;
for(int i = 0; i < 3; i++)
{
cin>>temp;
(*vecptr)[i] = temp;
}
veclen = (*vecptr).size();
}
int main()
{
getinput();
for(int i = 0; i < veclen; i++)
{
cout<<(*vecptr)[i]<<endl;
}
return 0;
}
Although I have mentioned the size as 10 you could make it a variant.
You need to dereference vecptr here to get the underlying vector:
cout << (*vecptr)[i] << endl;
You will also need to initialize vecptr.