C++ functions, arrays, and pointers - c++

There is already a lot about this but none solved my problem or maybe I just didn't understand the answers. I'm just simply trying to return an array from a function
Also, I am having to put all of my functions above the main function that also seems weird to me.
And here is what happens when I try to use pointers:
int * RookMoves(int startingPosition, bool isWhite, int theBoard[64]){
int startingPositionXY[2] = { startingPosition % 8, (startingPosition - (startingPosition % 8)) / 8 };
int possibleRookPositions[14];
int possiblePosXY[2];
int counter = 0;
for (int h = 0; h < 2; h++)
{
int counter2 = 1;
for (int j = 0; j < 2; j++)
{
counter2 *= -1;
for (int i = 1; i < 8; i++)
{
int other = startingPositionXY[h] + (i * counter2);
int hInverted = (h + abs(h - 1)) * abs(h - 1); // 0 + 1 * 1 = 1 but 1 + 0 * 0 = 0
if (other < 8 && other > -1)
{
possiblePosXY[h] = other;
possiblePosXY[hInverted] = startingPositionXY[hInverted];
int movesOneDim = possiblePosXY[0] + (possiblePosXY[1] * 8);
if (CalculateSameColor(isWhite, theBoard[movesOneDim])) {
possibleRookPositions[counter] = movesOneDim;
counter++;
if (CalculateEnemy(isWhite, theBoard[movesOneDim]))
{
break;
}
}
else
{
break;
}
}
else
{
break;
}
}
}
}
for (int i = counter; i < 14; i++) //simply changing any unused elements to -1 for later recognition
{
possibleRookPositions[i] = -1;
}
cout << sizeof(possibleRookPositions) / sizeof(possibleRookPositions[0]) << ' '; // returns 14 just as it should
return possibleRookPositions;
}
int main()
{
int testBoard[64];
for (int i = 0; i < 64; i++) {
testBoard[i] = 0;
}
int* arr = RookMoves(21, true, testBoard);
cout << sizeof(arr) / sizeof(arr[0]); //ouputs: 1, should be 14
}
by all things the web says the pointer one should work but it doesn't, it returns an array with a size of 1.

An array in C++, in “simple” code, is either std::vector or std::array. Those can be returned without any problem. I’d say your issue is that you are writing mostly C and calling it C++. C is IMHO much harder to get right for beginners - so use the fact that you got C++ available for your use!
The C-style arrays is something any professional C++ programmer of course fully understands, but whenever I’m forced to write code like that (due to what amounts to customer requirements), it almost never passes the tests on the first try. So don’t be too worried: even people who can write a compiler that could take this array code and produce assembly output still have trouble with getting it right to some extent. It’s unwieldy and it has almost no place in C++ of today.

I was trying to get sizeof from a pointer because I don't really understand how those work yet but all I needed to do was to use pointers but just initialize the array I was returning as "static." Thanks to MikeCAT

Related

Round robin algorithm in a loop

How round-robin algorithm can be implemented that runs in a loop for ever?
for (int i = 0; ;i++){
roundRobinIndex = i % numberOfWorkers;
}
The problems with the way above is that integer overflow problem. It can also be implemented with checking the value of i:
for (int i = 0; ;i++){
roundRobinIndex = i % numberOfWorkers;
if i == maxNumber{
i = 0;
}
}
But this way seems ugly. Maybe there is more elegant way?
Why not ?
int numberOfWorkers = 10
int roundRobinIndex = numberOfWorkers - 1
while(true){
roundRobinIndex = (roundRobinIndex + 1) % numberOfWorkers
}
or with a for-loop
for (int i = 0; ;i = (i + 1) % numberOfWorkers){
roundRobinIndex = i;
}
We can now get rid of i
Avoiding any modulo call, we can do:
constexpr int nextRR(int curIdx, int sz) {
if(curIdx==sz-1) {
return 0;
}
return curIdx+1;
}
for (int rrIndex = 0;;rrIndex = nextRR(rrIndex, sz)) {
// use rrIndex here ...
}
This will be performance-wise more effective than any modulo-based solution, if the number of workers is not known at compile time.
Note that nextRR can also be written like this, to optimize even further for platforms where comparison with 0 is faster than a comparison with a variable:
constexpr int nextRR(int curIdx, int sz) {
if(curIdx==0) {
return sz-1;
}
return curIdx-1;
}
For completeness (I agree that pLopeGG's answer is more elegant) - your way would work perfectly well if you make i an unsigned int rather than int since the overflow is defined in the standard for unsigned overflows, but not signed.
ie
for (unsigned int i = 0; ;i++){
roundRobinIndex = i % numberOfWorkers;
}
Why not put the % into the loop?
for (int i = 0; ;++i, i %= numberOfWorkers)
{
}

How to write a recursive function that jumbles up numbers from 0 to 6 in a random manner?

Basically i want to write a function that takes values from 0 to 6 and gives back a random assortment such as 2,3,4,5,0,1,6. Here is the code that i came up with. However the problem is that the integer prev (meaning previous) does not store all the old values of r (random number) and thus some values end up being repeated. How might i fix this?
int s(int b)
{
// b is 7
int h = b-1;
int prev = -1;// to store the previous r value
srand(time(0));
for (int i = 0; i < b; i++)
{
int r = rand()%(h - 0 + 1) + 0;
if (r != prev)
{
cout << r << endl;
prev = r;
}
else if (r == prev)
{
s(b);
}
}
return 0;
}
From the comments, this sounds more like a homework problem than a practical problem because you said "No arrays allowed". But I suppose it is an interesting problem.
Here's some code, in Java with only loops, if statements, and with no arrays, as required.
It outputs a random permutation of the set 0, 1, ..., N, shuffled with the Fisher-Yates algorithm.
void printRandom(int N) {
long used = 0;
for (int i = 0; i < N; i++) {
int randomIndex = ThreadLocalRandom.current().nextInt(N - Long.bitCount(used));
for (int j = 0; j < N; j++) {
if ((used & (1L << j)) == 0) {
if (randomIndex-- == 0) {
System.out.print(j + " ");
used = used | (1L << j);
break;
}
}
}
}
}
It is unfortunately limited to the size of a long on your system :)
I think the best way to solve this problem is by using an aux funtion that stores in a variable all the numbers printed until the moment, check if the new number is in the used numbers variable, if not add it to the variable (you can use strings? I know that they are arrays of char's but maybe you can)
Something like this:
function aux(int b, char *variables_printed, int iterations_left)
if (b = 0) then print variables_printed
else
int n = generate_random_number() %b
while (n in variables_printed)
n= (n+random_number) % b
variables_printed += n
aux(b, variables_printed, iterations_left-1)
And your other function:
function s(b)
if b < 0 return 0
else
char *variables_to_print
aux(b, variables_to_print, b)
If you can not use strings, you can do it with long as konsolas said.

separating bayer image to color channel c++

I have a raw image with different Bayer pattern.
this is what i have implemented in order to separate the channels.
speed is very important here since this is going to run on thousands of large images.
can you please suggest code optimizations.
I know % (modulo) isn't very fast how can i replace this for example?
thanks
void Utilities::SeparateChannels(int** _image, int*& gr, int*& r, int*& b, int*& gb,int _width, int _height, int _colorOrder)
{
//swith case the color Order
int counter_R = 0;
int counter_GR = 0;
int counter_GB = 0;
int counter_B = 0;
switch (_colorOrder)
{
//rggb
case 0:
for (int i = 0; i < _height; i++)
{
for (int j = 0; j < _width; j++)
{
if (i % 2 == 0 && j % 2 == 0)
{
r[counter_R] = _image[i][j];
counter_R++;
}
else if (i % 2 == 0 && j % 2 == 1)
{
gr[counter_GR] = _image[i][j];
counter_GR++;
}
else if (i % 2 == 1 && j % 2 == 0)
{
gb[counter_GB] = _image[i][j];
counter_GB++;
}
else if (i % 2 == 1 && j % 2 == 1)
{
b[counter_B] = _image[i][j];
counter_B++;
}
}
}
break;
default:
break;
}
}
One possibility that might be worth considering would be to set up the arrays for the destination channel data as an array itself:
int *channels[] = {r, gr, gb, b};
Likewise, set up the counters as an array:
int counters[4] = {0};
...then your code could come out something like this:
for (int i=0; i<_height; i++)
for (int j=0; j<_width; j++) {
channel = (i&1) << 1 + (j&1);
int &counter = counters[channel];
channels[channel][counter++] = image[i][j];
}
The basic idea is that we combine the low bits of the i and j into a single number that we can use as a channel address. Then we use that number to index into the channel and the counter for that channel.
It's possible your compiler is already optimizing the existing code to be roughly equivalent to this (or possibly even better than this produces), but it's also possible it isn't.
I wouldn't normally expect a lot of improvement (at least on a typical desktop computer) though. I'd expect the bottleneck to be the bandwidth to main memory, almost regardless of the details of how you write the loop.
You should unroll the loop to process in 2x2 blocks. This way you will always know the parities and won't need to test them.
r[counter_R] = _image[i][j];
counter_R++;
gr[counter_GR] = _image[i][j+1];
counter_GR++;
gb[counter_GB] = _image[i+1][j];
counter_GB++;
b[counter_B] = _image[i+1][j+1];
counter_B++;
(Also adapt the loop parameters.)

C++ memory: deleting an unused array of bool can change the result from right to wrong

I am trying to solve Project Euler Problem 88, and I did it without too much effort; however, I find that some seemingly irrelevant code in my program is affecting the result. Here's my complete code (it's not short, but I cannot locate the error. I believe it would be obvious to more experienced eyes, so please read my description first):
#include <iostream>
#include <set>
using namespace std;
bool m[24001][12001];
bool p[24001]; // <------------ deleting this line will cause error in result!
long long answer[12001];
int main() {
long long i;
long long j;
long long l;
set<long long> all;
long long s = 0;
for (i = 0; i <= 24000; i++) {
for (j = 0; j <= 12000; j++) {
m[i][j] = false;
}
}
m[1][1] = true;
for (i = 2; i <= 24000; i++) {
m[i][1] = true;
for (j = 2; (j <= i) && (i * j <=24000); j++) {
for (l = 1; l <= i; l++) {
if (m[i][l]) {
m[i * j][l + 1 + (i * j) - i - j] = true;
}
}
}
}
for (i = 0; i <= 24000; i++) {
for (j = 0; j <= 12000; j++) {
if (m[i][j] && (answer[j] == 0)) {
answer[j] = i;
}
}
}
for (i = 2; i <= 12000; i++) {
cout << answer[i] << endl;
all.insert(answer[i]);
}
cout << all.size() << endl;
for (set<long long>::iterator it = all.begin(); it != all.end(); it++) {
//cout << *it << endl;
s += *it;
}
cout << s << endl;
}
With the "useless" bool array, all the answers are right, between 0 and 24000; but without it, some answers in the middle got corrupted and become very large numbers.
I am completely confused now; why would that unused array affect the middle of the answer array?
Thanks and sorry for the long code! I will be grateful if someone could edit the code into a better example, I simply son't know what is with the code.
You do a silly thing in here:
m[i * j][l + 1 + (i * j) - i - j] = true;
Say, i=160, j=150, l=1... You will try to access m[24000][23692]... And you corrupt the stack, so behavior is undefined.
Next time try to use some profiler and/or debugger.
Add:
#include <cassert>
at the begining and
assert( (i * j) * 12001 + (l + 1 + (i * j) - i - j) <= 12001*24001 );
before the following line:
m[i * j][l + 1 + (i * j) - i - j] = true;
The assertion will fail, which means you write outside the bounds of the array m.
As requested, adding this to an answer.
You are definitely writing beyond the bounds of the array m somewhere, when the unused array p exists, m overwrites in to its contents which doesn't affect the answer array but once p is removed the overwriting happens in to answer array showing up the problems.
Overwriting beyond the bounds of the array is an Undefined Behavior and it causes your program to be ill-formed. With Undefined Behavior all safe bets are off and any behavior is possible. While your program may work sometimes or crash sometimes or give incorrect results.Practically, Anything is possible and the behavior may or even may not be explainable.
In one of your nested loops you use l as the index for the second dimension. This variable can run from 0 to i and i, in turn, can run from 0 to 24000. Since your second dimension of the array can only be index from 0 to 12000 this causes a classic out of range error. This also nicely explains why adding an extra array avoid the problem: the out of range accesses go to the "unused" array rather than overwriting the result.

C++: delete strange behaviour

I have started doing some stuff with dynamic allocation in C++ but I had some problems. Here's the code:
nrMare(char cifS[], char* startPos = new char())
{
n = 0;
int i;
cif = startPos;
printf("%p %i\n", cif, (cif - (char*)NULL) % 8);
for(i = strlen(cifS) - 1; i >= 0; i--)
{
cif--;
n++;
cif = new(cif) char(cifS[i] - '0');
}
}
~nrMare()
{
int i;
for(i = 0; i < n; i++)
{
delete(cif);
cif++;
}
n = 0;
cif = 0;
}
nrMare is a class (it comes from bigNumber in Romanian :D) which is supposed to be able to contain the digits of a big number.
The problem is that the destructor (~nrMare) gives a weird error, when I make a variable nrMare something() on my computer, but it works for 116 digits long ones.
Do you have any suggestion or explainations?
EDIT: cif is a (char*) type
EDIT #2: n is the length of the number. I use the char pointer this way because I want to be able to add (like n++; cif--; cif = new(cif) char(number_to_add); -> this would add number_to_add in the left side of cif) and draw elements from both sides.
EDIT #3: this is gonna be a long one... Sorry for being such a bad explainer and thanks for your patience.here are some operators:
void operator-=(nrMare nr2)
{
int i;
for(i = 1; i <= n && i <= nr2.n; i++)
cif[n - i] -= nr2[nr2.n - i];
for(i = n - 1; i >= 0; i--)
{
if(cif[i] < 0)
{
cif[i] += 10;
cif[i - 1]--;
}
}
while(cif[0] == 0)
{
cif++;
n--;
//delete(cif - 1);
}
}
int operator/=(int nr)
{
int i;
for(i = 0; i < n - 1; i++)
{
cif[i + 1] += (cif[i] % nr) * 10;
cif[i] = cif[i] / nr;
}
i = cif[n - 1] % nr;
cif[n - 1] /= nr;
while(cif[0] == 0)
{
cif++;
n--;
//delete(cif - 1);
}
return i; // the return value is this big number % nr
}
void operator*=(int cifTimes)
{
int i;
for(i = 0; i < n; i++)
{
cif[i] *= cifTimes;
}
for(i = n - 1; i >= 0; i--)
{
if(cif[i] > 9)
{
if(i != 0)
{
cif[i - 1]++;
cif[i] %= 10;
}
else
{
n++;
cif[0] %= 10;
cif--;
cif = new(cif) char(cif[0] = 1);
}
}
}
}
EDIT #4: n = length of the number = number of digits = number of bytes. Weird error means it just crashes. I don't know how to find more about it. MinGW compiler asks Visual Studio (Visual C++) to debug it because it has some problems. This is for a problem, and somewhere (in the evaluator) it says "Killed by signal 6(SIGABRT)", if this helps.
EDIT #...: #Branko Dimitrijevic: I don't wanna be lazy... I want my own... I had this problem in more attempts to make something running. If I take out the destructor, it works just fine, just I guess then it would be a memory leak that way... I really want to find out why would this occur... and only for specific sizes and, i.e. it doesn't crash on the first "delete", but on the 11'th in my case, that's why it's weird .
The delete can only work correctly on an address that is at the beginning of a dynamically-allocated block.
The cif will fail one or both of these conditions, leading to undefined behavior when the destructor calls delete, for following reasons:
You assign startPos to cif and then modify it in a very strange way before calling the placement new. So even if startPos is a properly allocated block of dynamic memory, the cif no longer points to the starting address of it.
If the caller passes an address of a stack-based variable to startPos, then you no longer deal with dynamic memory at all.
Not to mention that you call new and delete in a loop - what's up with that? There is also a fair chance for bombarding the memory unless you craft your input parameters in a very specific way. This whole block of code looks suspicious, what exactly are you trying to do?