I'm new/noob programmer of C++, and I've this problem. I want to pass a pointer of double to a function (which will process some data on it) and read (after the process) a fixed value of that "array". I've do this:
void ReadDoubles(double* samples, int size)
{
for (int i=0; i < size; ++i)
{
*samples = i*10.1;
samples++;
}
}
int main()
{
int size = 10;
double *values=0;
ReadDoubles(values, size);
cout << *(values+3);
}
BUt of course it seems I can't init the pointer that way. I think I need to init the pointer allocating 10 values? Tried:
double *values[size];
but that's not the solution. How would you do this simple task?
You need to allocate the array at first. Here you are
#include <iostream>
void ReadDoubles( double* samples, size_t size )
{
for ( size_t i = 0; i < size; ++i )
{
*samples = i*10.1;
samples++;
}
}
int main()
{
size_t size = 10;
double *values = new double[size];
// ^^^^^^^^^^^^^^^^
ReadDoubles( values, size );
std::cout << *(values+3) << std::endl;
delete []values;
}
The program output is
30.3
If you don't want to use the operator new then there are two general approaches. Either you can declare an array as for example
int main()
{
const size_t size = 10;
//^^^^
double values[size];
// ^^^^^^^^^^^^
ReadDoubles( values, size );
std::cout << *(values+3) << std::endl;
}
or you can use standard class std::vector<double>.In this case the function should be rewritten appropriately.
For example
#include <iostream>
#include <vector>
void ReadDoubles( std::vector<double> &samples, size_t size )
{
samples.resize( size );
for ( size_t i = 0; i < size; ++i )
{
samples[i] = i*10.1;
}
}
int main()
{
size_t size = 10;
std::vector<double> values;
ReadDoubles( values, size );
std::cout << values[3] << std::endl;
}
If you are not allowed to change the RealDoubles function and you must have a function return the size then the following should work:
#include <string>
#include <iostream>
#include <math.h>
#include <cmath>
using namespace std;
void ReadDoubles(double* samples,int size)
{
for (int i=0; i < size; ++i) {
*samples = i*10.1;
samples++;
}
}
int get_size()
{
return 10;
}
int main()
{
int size = get_size(); // get size from function
//double *values=0;
double *values = new double[size] {0}; // Use new to allocate array. Optional: use {0} to init first element to 0, others default initialized to 0
ReadDoubles(values,size);
cout << *(values+3);
delete[] values;
}
If you prefer to avoid new and delete then you can let a std::vector manage the container for you:
#include <string>
#include <iostream>
#include <math.h>
#include <cmath>
#include <vector>
using namespace std;
void ReadDoubles(double* samples,int size)
{
for (int i=0; i < size; ++i) {
*samples = i*10.1;
samples++;
}
}
int get_size()
{
return 10;
}
int main()
{
int size = get_size(); // get size from function
//double *values=0;
std::vector<double> value_container(size,0); // vector will do the new and delete for us
double *values = value_container.data();
ReadDoubles(values,size);
cout << *(values+3);
} // vector destructor will do delete when it goes out of scope
Related
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;
}
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.
I have a program where I want to pass an array - in this case k[arrsize], which is a parameter of the funciton fillArray() to the other function create_file() (the same array, filled with the random numbers). However, I cannot pass the same array and I would like to ask how can this be done?
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <time.h>
#include <stdlib.h>
using namespace std;
const int arrsize = 20;
//int a[arrsize];
fstream p;
void fillArray(int k[arrsize])
{
srand((unsigned)time(NULL));
for (int i = 0; i<20; i++)
{
if (i % 2 == 0)
{
k[i] = -(rand() % 100);
}
else
{
k[i] = (rand() % 100);
}
}
}
void create_file(int k[arrsize])
{
p.open("danni.dat", ios::out);
for (int i = 0; i<20; i++)
{
p << k[i] << endl;
}
p.close();
}
int main() {
fillArray(k);
create_file(k);
return 0;
}
You simply forget to define an array:
int main() {
int k[arrsize];
fillArray(k);
create_file(k);
}
Usually you don't want to pass the whole array, instead you might want to pass a reference to it. I suggest you to use std::array instead of a C-style arrays.
#include <array>
void fill(std::array<int, 1>& a)
{
a[0] = 0;
}
int main()
{
std::array<int, 1> a = {};
fill(a);
return 0;
}
Why is the program below crashing? I tried debugging the code but couldn't understand; I am suspecting that either the program is wrong or the memory to the passed pointer to display function should have been initialized.
#include <iostream>
using namespace std;
int display( int** intarray )
{
int size = 0;
while( size < 10 )
{
*intarray[size] = size;
size++;
}
return size;
}
int main() {
int* intptrarray;
int arraysize = 0;
arraysize = display( &intptrarray );
for ( int indx = 0; indx < arraysize; indx++ )
{
std::cout << intptrarray[indx] << std::endl;
}
return 0;
}
When a pointer is declared, it doesn't point to any specific memory address. To have it point somewhere, you need to allocate memory to it as follows:
#include <iostream>
using namespace std;
int display( int** intarray, int arraysize )
{
int size = 0;
while( size < arraysize )
{
(*intarray)[size] = size;
size++;
}
return size;
}
int main() {
int arraysize = 10;
int* intptrarray = new int[arraysize];
arraysize = display( &intptrarray, arraysize );
for ( int indx = 0; indx < arraysize; indx++ )
{
std::cout << intptrarray[indx] << std::endl;
}
delete[] intptrarray;
return 0;
}
Whenever you allocate memory, you need to remember to deallocate it yourself (delete for a single variable, delete[] for an array).
*intarray[size] should be (*intarray)[size].
However you have not yet allocated any memory either, so in both cases you are causing undefined behaviour by writing through an uninitialized pointer.
A correct way to write this program is:
void display( std::vector<int> &vec )
{
vec.resize(10);
for ( int i = 0; i < 10; ++i )
vec[i] = i;
}
int main()
{
std::vector<int> vec;
display(vec);
for ( int indx = 0; indx < vec.size(); indx++ )
{
std::cout << vec[indx] << std::endl;
}
}
This can be improved by using std::iota and range-based for-loops if you have a modern compiler.
Hi I'm a beginner level programmer and I have an issue with a program I've been working on. The point is to create a an individual class that has an array consisting of random generated numbers as one private variable, a size for the array, and a number representing the fitness of the individual through the use of the array.
It utilizes a header file, the source file for the header, and source file to test the header. For some reason, whenever I try to compile I reach a breakpoint, and Visual Studio doesn't tell me what the error is. I suspect it has something to do with the private pointer in my class but I don't know why or how to fix the error.
Header
#ifndef INDIVIDUAL_H
#define INDIVIDUAL_H
class individual
{
int size;
double fitness;
double* genotype;
public:
individual(int pSize = 10);
individual(const individual& copy);
~individual();
double* getGenotype();
double getFitness();
int getSize();
void mutation();
void crossover(individual a);
};
#endif
Header source
#include <iostream>
#include <string>
#include <stdlib.h>
#include <time.h>
#define M_PI 3.14159265358979323846
#define M_E 2.71828182845904523536
#include <cmath>
#include "individual.h"
using namespace std;
double RandomFloat(double min = -32.768, double max = 32.768)
{
min = min;
max = max;
unsigned int seed;
seed = (unsigned int) time(0) + rand();
srand(seed);
double r = (double)rand() / (double)RAND_MAX;
return min + r * (max - min);
}
double Fitness(double a[], int size)
{
double fitness;
double firstSum, secondSum;
firstSum = 0;
for(int i = 0; i<size; i++)
{
firstSum += a[i]*a[i];
}
firstSum /= size;
secondSum = 0;
for(int i = 0; i<size; i++)
{
secondSum += cos(2*M_PI*a[i]);
}
secondSum /= size;
fitness = -20*exp(-0.2*sqrt(firstSum) - exp(secondSum) + 20 + M_E);
return fitness;
}
individual::individual(int pSize)
{
size = pSize;
genotype = nullptr;
genotype = new double(size);
for(int i = 0; i<size; i++)
{
genotype[i] = RandomFloat();
}
fitness = Fitness(genotype,size);
}
individual::individual(const individual& copy)
:size(copy.size),genotype(new double[copy.size])
{
std::copy(copy.genotype, copy.genotype + copy.size, genotype);
}
individual::~individual()
{
delete[] genotype;
}
double* individual::getGenotype()//returns a pointer
{
return genotype;
}
double individual::getFitness()
{
return fitness;
}
int individual::getSize()
{
return size;
}
void individual::mutation()
{
int first, second;
double temp;
first = (int)RandomFloat();
second = (int)RandomFloat();
temp = genotype[first];
genotype[first] = genotype[second];
genotype[second] = temp;
}
void individual::crossover(individual a)
{
int crossPoint = size/3 - 1;
for(int i = crossPoint; i<size; i++)
{
double temp1;
temp1 = 0;
temp1 = genotype[i];
genotype[i] = a.genotype[i];
a.genotype[i] = temp1;
}
}
Driver source
#include <iostream>
#include <string>
#include <stdlib.h>
#include <cmath>
#include <vector>
#include "individual.h"
#define M_PI 3.14159265358979323846
#define M_E 2.71828182845904523536
using namespace std;
int main()
{
individual test;
int size = test.getSize();
cout << size << endl;
for(int i = 0; i<size; i++)
{
cout << test.getGenotype()[i] << endl;
}
return 0;
}
I've tried searching for possible solutions (added the copy constructor and destructor) and nothing seems to resolve the problem.
Any help would be much appreciated.
To allocate an array of double
Change:
genotype = new double(size); // this initialize one double and initialize value to size
TO
genotype = new double[size]; // this creates an array which size is 'size'
Your code overruns memory when you only allocate one double and write data to memory
for(int i = 0; i<size; i++)
{
genotype[i] = RandomFloat();
}