Reference to a static 2D array? - c++

I have some 2D arrays of a static size:
double quickStats[NUM_REPETITIONS][NUM_TRIALS];
double mergeStats[NUM_REPETITIONS][NUM_TRIALS];
double bstStats[NUM_REPETITIONS][NUM_TRIALS];
Later, I want a reference to one of them:
double stats[NUM_REPETITIONS][NUM_TRIALS];
if(i == 0) {
stats = quickStats;
}
else if(i == 1) {
stats = mergeStats;
}
else if(i == 2) {
stats = bstStats;
}
However, this does not work.
What can I do to do what I am trying to do without nested for loops to manually copy each element into the reference array?
I just need to read from stats, it is to avoid redundant code.
Thanks

Try this:
#define NUM_REPETITIONS 10
#define NUM_TRIALS 10
double quickStats[NUM_REPETITIONS][NUM_TRIALS];
double mergeStats[NUM_REPETITIONS][NUM_TRIALS];
double bstStats[NUM_REPETITIONS][NUM_TRIALS];
int main(){
double (* ptr)[NUM_TRIALS] =quickStats;
}

Create a pointer to it like this:
double (*stats)[NUM_REPETITIONS][NUM_TRIALS];
Since your dimensions are known at compile time you can use std::array<> which is more versatile and readable:
std::array<std::array<double, NUM_TRIALS>, NUM_REPETITIONS> stat;

References have to be initialized upon declaration so you cannot assign it later on. Your best bet is using a pointer or declare the reference inside the if branches.
constexpr unsigned int N = 100;
double a[N][N] = {0};
/* Pointer. In your case, N should be NUM_TRAILS here */
double (*a_ptr)[N] = a;
/* Specified Reference Type */
double (&a_ref)[N][N] = a;
/* C++11 Auto Reference */
auto &a_autoref = a;
Test here: Coliru

Related

Do dynamic structs need to be deleted if given value from a function?

Sorry if the question is hard to understand but I wasn't sure how to word it.
Say for example I had a struct like the following,
struct Days {
int counter;
};
And in main I had
Days *d = new Days;
d.counter = 0;
If I then use d in a loop like this inside main
do {
int num = rand()%900+1000;
d = add(d, num);
} while(user decides to continue}
delete d;
where the function add is as follows
Days *add(Days *d, int num) {
Days *temp2 = new Days;
temp2.counter = 0;
if (d.counter > 0)
temp2.counter = d.counter;
temp2.counter += num;
return temp2;
]
Do I need to delete d after each iteration of the do-while loop since its copying over?
If so, would it be in the add function in the if statement like this
if (d.counter > 0) {
temp2.counter = d.counter;
delete d;
}
Or would it be in the loop in main?
Actually, you don't need to allocate anything yourself.
In the main function, just declare your variable as:
// Create a Days object with counter initialized to zero
Days d {0};
Then, you can define your add function like that:
void add(Days & d, int num)
{
d.counter += num;
}
Or if you really want to use pointers instead of references:
void add(Days * d, int num)
{
d->counter += num;
}
Finally, you can just call it as follows:
do
{
int num = whatever();
add(d, num);
// add(&d, num); if you used the pointer version
}
while(condition);
If I may give you an advice, since add() is supposed to operate on a Days object, it may make sense to make it a member function of Days so that you wouldn't need to pass a Days as argument and get rid of the pointers/references stuff ^^
In that case,
add(d, num);
Would become:
d.add(num);

Static array size determined from template values

I'm trying to use static array which size needs to be determined by given template values. However size will be constant across program runtime - thats why I decided not to use std::vector.
template<uint32_t BAR_WIDTH>
class Bar
{
//do_stuff...
Foo mapper[ [&]()->int{ uint32_t tmp = BAR_WIDTH / Foo:FOO_EDGE; return (BAR_WIDTH % 10 == 0) ? tmp : tmp + 1; }; ];
};
FOO_EGDE is const static value. IDE gives me a hint that
Array size expression must have an integer type instead of int(*)()
I wonder if I can make it work this way without using std::vector. Any advice is welcomed and appreciated.
The problem is, that you are using a lambda for determining the size of the array. If you leave it off and just use the ternary operator, it works:
int main() {
const bool z = true;
const int x = 5, y = 3;
int arr[z ? x : y];
return 0;
}
Ideone
As opposed to:
int main() {
const bool z = true;
const int x = 5, y = 3;
int arr[[&]() -> int { return z ? x : y; }];
return 0;
}
Ideone
As described here, lambda expressions can't be constexpr yet, and you can only declare the size of an array with a constexpr value (even then, you are not trying to invoke declared lambda (to invoke it - () is required at the end of declaration).
To work around such problem, you could use a private static constexpr method, and use the return value of it, for the array size declaration:
static constexpr uint32_t GetArraySize ()
{
uint32_t tmp = BAR_WIDTH / Foo::FOO_EDGE;
return (BAR_WIDTH % 10 == 0) ? tmp : tmp + 1;
}
Foo mapper[GetArraySize ()];

Get return of a function without sending anything

I have a function header:
double countThis(double counter);
Then, in my main I do this:
double test = 10;
countThis(test);
Then comes the function:
double countThis(double counter) {
double counted = counter;
return counted;
}
On the bottom, I have one last function, and here I want to get double counted without having to do countThis(something), I just want to get the return from the previous call that was made in main and get the value 10 (counted).
One way to achieve this sort of persistence is to use a class and define an instance of that class:
struct Counter
{
double counted;
double countThis(double counter)
{
return counted = counter; // assign counter to counted, and return that value.
}
};
At the point of use:
int main()
{
Counter c;
c.countThis(10);
// c.counted contains the last value sent to countThis, in this case, 10
}
The instance c is used to persist the value that you pass to countThis.
Do this:
double test = 10;
double ret;
ret = countThis(test);
// Now the value returned by countThis is in ret
You can use global variable.(double counted) and in the function
double countThis(double counter) {
counted = counter;
return counted;
}
define another function to just return counted
double count() {
return counted;
}
But,i suggest you to create a struct and make getter and setter on it.
Why not just copy the value into a new instance of double?
Example:
double test = 10;
countThis(test);
double something = test;

How to modify array inside function which doesn't take this array as parameter

What I need is to modify pTab array inside modifyAA(int a) function.
How can I achieve this?
Example Code:
int modifyAA(int a);
int main()
{
*pTab=new int[10]; int a=13;
for(int i=0;i<=9;i++)
pTab[i]=88;
modifyAA(a);
//I'd like to have pTab to be modified after function invoke
return 0;
}
modifyAA(int a){
for(int i=0;i<=9;i++)
pTab[i]=pTab[i]+1;
a=a+pTab[0];
return a;
};
Is it possible to modify array when function doesn't take it as parameter ?
You can use a global variable for the pointer to the first element of the dynamic array:
int * pTab;
int printAA(int a)
{
for (unsigned int i = 0 i != 10; ++i)
{
++pTab[i];
}
return a + pTab[0];
}
int main()
{
pTab = new int[10];
// populate
printAA(13);
}
You could use global variables. This could be practical especially if several functions like printAA() would need to call it.
However there is a risk of using *pTab before it's allocated. And also, you remember now the size, but if later you'd change the size to 10, you would have to find back all the places where you've hardcoded the 10 or the 9.
If the goal of not passing the parameter is mainly because you call the function a lot of times you could opt for a std::bind, creating a kind of dynamic function:
#include <iostream>
#include <functional>
int printDynArr(int* dynarr, size_t sz, int a) // proper function with all parameters
{
for (size_t i = 0; i < sz; i++)
dynarr[i]++; // It's a pointer, so you modify the data where it is stored
a += dynarr[0];
return a;
};
int main()
{
int *pTab = new int[10]; int a = 13; //declaring and alocating - dynamic array
auto printAA = std::bind<int>(printDynArr, pTab, 10, std::placeholders::_1); // dynamic function shortcut with predefind parameters
...
printAA(a); //using function without giving pTab as argument.
std::cin.get();
return 0;
}
If you were to do this "The C++ way", you could use a vector and iterators from stdlib, like so:
#include <vector>
typedef std::vector<int> PTab; // Defines a type for your pTab, it's a vector of integers
int printAA(PTab::iterator from, PTab::iterator until, int a); //declaring some func
int main()
{
PTab pTab(10, 88); // Initializes pTab vector to 10 elements all containing 88
int a = 0;
printAA(pTab.begin(), pTab.begin() + 10, a);
return 0;
}
int printAA(PTab::iterator from, PTab::iterator until, int a)
{
for (PTab::iterator i = from; i != until; ++i)
{
*i++; // Increments current element by 1
}
a += *from; // Adds the value of the from element to a
return a;
};
This way you don't pass the vector itself to the function, instead, you only pass a range of iterators, which gives the function a possibility to access the contents of the vector, but not to modify the vector object itself (ie. clear it, resize it, etc.).

return pointers from function. Value not updated for one pointer

I have tried to obtain 2 pointers from a function and print it in main. the vague thing is one pointer seems to have recovered its values, while the other hasn't. And both the pointers, have the correct value inside the calling function, just before returning as well. Please tell me if you can identify any programmatic error that is preventing me from getting the right answer.
#include<iostream>
#include<fstream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
double* readctrls()
{
fstream inputs;
inputs.open("input_coods.txt");
int nol = 0,i = 0;
string line,temp,subtemptrans,subtemprots;
while(getline(inputs,line))
{
++nol;
}
// cout<<nol<<endl;
inputs.close();
inputs.open("input_coods.txt");
string *lines = new (nothrow) string[nol];
double* trans = new double[nol];
double* rots = new double[nol];
trans[0] =float(nol);
for(int i = 0; i<nol ; i++)
{
getline(inputs,lines[i]);
// cout<<lines[i]<<endl;
temp = lines[i];
// cout<<temp<<endl;
for(int j = 0; j<temp.length() ; j++)
{
if(temp.at(j) == ' ')
{
subtemptrans = temp.substr(0,j);
subtemprots = temp.substr(j+1,temp.length()-j);
// cout<<subtemprots<<endl;
*(trans+i+1) = ::atof(subtemptrans.c_str());
*(rots+i) = float(atoi(subtemprots.c_str()));
// cout<<rots[i]<<endl;
}
}
}
inputs.close();
// cout<<rots[2]<<endl;
return(rots,trans);
}
int main()
{
double *trans,*rots;
(rots,trans) = readctrls();
// cout<<sizeof(trans)<<endl;
for(int i=0;i<trans[0];i++)
{
cout<<*(trans+i)<<endl;
cout<<*(rots+i)<<endl;
}
}
The value of Trans is written fine in the memory and is perfectly retained from the main(). But the rots is giving garbage values of the order (e^-42). Please help me here.
C++ is neither Python nor Lua.
You can't return multiple values from a function.
return rots, trans;
This is the comma operator - evaluates its operands and yields the last (rightmost) one.
(rots, trans) = readctrls();
Likewise, this assigns to trans only, rots will be uninitialized.
Solution: you can either return a struct containing the two pointers, or pass them by reference, or whatever...
struct Foo {
double *rots;
double *trans;
};
Foo readctrls()
{
// ...
Foo r;
r.rots = rots;
r.trans = trans;
return r;
}
or:
void readctrls(double *&r, double *&t)
{
// ...
r = rots;
t = trans;
}
Other remarks:
Don't use raw arrays. std::vector<T> is generally preferred over T * in C++.
It's super wasteful to read the entire file just in order to count the lines, then read it once again to actually parse its contents. If you used an std::vector<double>, you could just vector.push_back(some_double); as you go along the lines, so you wouldn't have to walk through the file twice (you know, I/O is expensive, especially if the file is large).
You never delete the pointers that you allocate using new - here your program leaks memory.