cout statement change program semantics - c++

I have the following piece of code, which is part of a class, whose details hopefully are not important for answering that question. I don't want an exact solution to my problem, but only an explanation, how the behavior, I'm going to describe, can occur.
Character operator+(Character c) {
std::vector<float> resDensity(density);
float l;
float dh;
for (int i = 0; i < domains.size(); i++) {
for (int j = 0; j < c.domains.size(); j++) {
l = (domains[i].intersection(c.domains[j])).length();
//std::cout << l;
dh = c.density[j] * l / domains[i].length();
resDensity[i] += dh;
}
}
std::vector<Domain> h(domains);
return Character(h, resDensity);
}
You probably noticed the commented cout statement. Due to a numeric bug in my program, I followed the falsy value until I detected the variable l. So I printed it to the console and found out, that the value is exactly the value I need, and also the program works just fine and the bug simply vanished. Uncommenting it, again, leads to the undesired misbehavior.
The Character class contains the fields domains and density, both vectors...
The length and intersection method:
float length() {
float res;
for (int i = 0; i < is.size(); i++) {
res += is[i].b - is[i].a;
}
return res;
}
Domain intersection(Domain d) {
std::vector<Interval> hi;
for (auto i = is.begin(); i != is.end(); i++) {
for (auto j = d.is.begin(); j != d.is.end(); j++) {
hi.push_back(i->intersection(*j));
}
}
Domain hhh(hi);
return hhh;
}
I compiled the code with g++ --std=c++11 ...
g++ --version
g++ (GCC) 4.8.2 20131219 (prerelease)

In your length() function the res variable is uninitialized:
float res;
for (int i = 0; i < is.size(); i++) {
res += is[i].b - is[i].a; // <-- uses an uninitialized res
}

How is length() calculated on Domain? hhh is a local variable that you are returning, so a copy will be made. If length() depends on something that is not copied then you will see strange behaviour. What if you just change intersection() to return a float or create a different method called intersectionLength() which returns a float - do you still get the heisenbug?

Related

C++ STL Map : Map.count(element) takes less time than Map[element]

I was trying this problem on leetcode,
https://leetcode.com/problems/naming-a-company/description/ .
I've observed the following
My Code :
long long distinctNames(vector<string>& ideas) {
unordered_map<string,bool> isPresent;
vector<vector<long long>> dp(26,vector<long long>(26,0));
int n = ideas.size();
long long ans = 0;
for(int i = 0; i < n; i++)
isPresent[ideas[i]] = true;
for(int i = 0; i < n; i++)
{
char x = ideas[i][0];
string ts = ideas[i];
for(int j = 0; j < 26; j++)
{
char y = 'a' + j;
ts[0] = y;
if(!isPresent[ts])
dp[x-'a'][j]++;
}
}
for(int i = 0; i < 26; i++)
{
for(int j = 0; j < 26; j++)
{
if(i==j) continue;
ans += (dp[i][j] * dp[j][i]);
}
}
return ans;
}
This code was getting TLE (85/89).
But, in the same code, if I replace
!isPresent[ts]
with
!isPresent.count(ts)
Same code runs much faster and passes.
Anyone can explain why ?
isPresent[ts] returns a reference to a map value object (so you can write isPresent[ts] = something. So if ts is not present in the map, then isPresent[ts] must default construct a map entry so that it has something to return a reference to. This is the reason that map::operator[] is not const.
isPresent.count(ts) has no such problems. If the ts key is not present then the map is unchanged.
operator[] on std::unordered_map inserts a default constructed element if none is yet present (which is also why the operator doesn't work on a const object.) Insertion potentially requires allocating memory or other somewhat slow things. Calling count does not, nor would e.g. find.

c++ int in class gets set to value, seemingly out of nowhere

The int winner should be set to 2 under certain conditions but it's somehow being set to a variety of higher values, most commonly 6. I have no idea how this is happening, as there is no other function in my class that affects winner, and the variable isn't even mentioned anywhere else in the program. What is most confusing to me is that I have an almost identical function (P2Move()) that is literally identical in how it sets the winner variable to P1Move(), and that function runs perfectly.
Some info: The class this is part of is called Board, which acts as a checkerboard array made up of Square class objects.
Below is the function causing the problem. Near the bottom, the statement else if((canTake.size()==0)&&(canMove.size()==0)) {Board::winner = 2;} causes the problem. Everything else seems to work when I remove the problematic part from the function, but I need that part to work in order to submit the final project.
void Board::P1Move()
{
P1pieces = 0;
std::vector <Move> canMove;
std::vector <Move> canTake;
for(int j = 0; j < bSize; j++)
{ //Start of j loop.
for(int i = 0; i < bSize; i++)
{ //Start of i loop.
Square sq = board[i][j];
bool cTakeL = canTakeL(i,j);
bool cTakeR = canTakeR(i,j);
bool cMoveL = canMoveL(i,j);
bool cMoveR = canMoveR(i,j);
if(board[i][j].getPl() == P1)
{
P1pieces++;
if(cTakeL)
{
Move a = Move(sq.getIndex(),board[i-2][j+2].getIndex(),board[i-1][j+1].getIndex(),0);
canTake.push_back(a);
}
if(cTakeR)
{
Move b = Move(sq.getIndex(),board[i+2][j+2].getIndex(),board[i+1][j+1].getIndex(),0);
canTake.push_back(b);
}
if(cMoveL)
{
Move c = Move(sq.getIndex(),board[i-1][j+1].getIndex(),0,0);
canMove.push_back(c);
}
if(cMoveR)
{
Move d = Move(sq.getIndex(),board[i+1][j+1].getIndex(),0,0);
setWinner(d.getSpos());
canMove.push_back(d);
}
}
} //End of i loop.
} //End of j loop.
if(canTake.size()!=0)
{
time_t t;
time(&t);
srand(t);
int moveNum = rand()%canTake.size();
std::string output = "p1 ";
Move out = canTake.at(moveNum);
int i = 0;
int j = 0;
for(int y = 0; y < bSize; y++)
{
for(int x = 0; x < bSize; x++)
{
if(board[x][y].getIndex()==out.getSpos())
{
i = x;
j = y;
}
}
}
if(board[i-2][j+2].getIndex()==out.getEndPos())
{
board[i-2][j+2].setOcc(true);
board[i-2][j+2].setPl(P1);
board[i-1][j+1].setOcc(false);
board[i-1][j+1].setPl(NA);
}
else if(board[i+2][j+2].getIndex()==out.getEndPos())
{
board[i+2][j+2].setOcc(true);
board[i+2][j+2].setPl(P1);
board[i+1][j+1].setOcc(false);
board[i+1][j+1].setPl(NA);
}
output = output + out.toString();
setCmove(output);
board[i][j].setOcc(false);
board[i][j].setPl(NA);
}
else if(canMove.size()!=0)
{
time_t t;
time(&t);
srand(t);
int moveNum = rand()%canMove.size();
std::string output = "p1 ";
Move out = canMove.at(moveNum);
int i = 0;
int j = 0;
for(int y = 0; y < bSize; y++)
{
for(int x = 0; x < bSize; x++)
{
if(board[x][y].getIndex()==out.getSpos())
{
i = x;
j = y;
}
}
}
if(board[i-1][j+1].getIndex()==out.getEndPos())
{
board[i-1][j+1].setOcc(true);
board[i-1][j+1].setPl(P1);
}
else if(board[i+1][j+1].getIndex()==out.getEndPos())
{
board[i+1][j+1].setOcc(true);
board[i+1][j+1].setPl(P1);
}
output = output + out.toString();
setCmove(output);
board[i][j].setOcc(false);
board[i][j].setPl(NA);
}
else if((canTake.size()==0)&&(canMove.size()==0))
{
Board::winner = 2;
}
P1pieces = canTake.size() + canMove.size();
}
You are working with std::vector, which is a good thing. (Too much beginner "C++" code uses C arrays.) The vector class template allows for a pretty easy way to find out if and where you might have an out-of-bounds access (as suggested in the comments):
Instead of accessing vector elements using operator[], change your code to use the .at() member function. .at() is bounds-checking, and will throw an exception if you access out-of-bounds (instead of silently breaking your program).
In production code, operator[] is usually preferred as omitting the bounds check is more efficient. But while learning, .at() can help you quite a bit.
Also, getting in the habit of using code checkers like valgrind or the assert macro to check your assumptions is a good thing, even when you got past the point where you wouldn't use .at() anymore.

C++ code crashing when using function instead of inline code

C++ rookie here.
I have the following code:
std::vector<float> MyBuffer::readAverage(int numberOfBuffers) {
std::vector<float> result = std::vector<float>(streams.size());
for (int i = 0; i < streams.size(); ++i) {
result[i] = getAverage(streams[i], numberOfBuffers);
}
return result;
}
float MyBuffer::getAverage(std::deque<float> input, int numberOfBuffers) {
float sum = 0;
for (int i = 0; i < numberOfBuffers; ++i) {
sum += input[i];
}
return sum / numberOfBuffers;
}
This code randomly crashes at getAverage(), I am not sure why.
Strange thing (for me as a C++ rookie at least) is that when I inline the function, it does not crash:
std::vector<float> MyBuffer::readAverage(int numberOfBuffers) {
std::vector<float> result = std::vector<float>(streams.size());
for (int i = 0; i < streams.size(); ++i) {
float sum = 0;
for (int i1 = 0; i1 < numberOfBuffers; ++i1) {
sum += streams[i][i1];
}
result[i] = sum / numberOfBuffers;
}
return result;
}
I can understand that there may be many reasons why this specific code is crashing - so my question relates more to what changes when I inline it, rather than calling a function? In my mind it should be exactly the same thing, but I guess there is something about the way C++ works that I am not grasping?
The program has many potential reasons why it can cause a crash.
bufferDurationMs is not initialized in the provided code, I hope its initialized to value other than 0.
for (int i = 0; i < streams.size(); ++i) {
result[i] = getAverage(streams[i], numberOfBuffers); } use result.size() instead of streams.size() as result is lvalue. It
is better to check both of these conditions in for.
It is quite possible that numberOfBuffers can be 0 in which case code would crash(divide by zero)
Some optimizations that can be done in the code:
std::vector<float> result = std::vector<float>(streams.size()); use reserve rather than using a costly operation of creating a
vector and assigning it to lvalue.
std::vector result; result.reserve(streams.size());
float MyBuffer::getAverage(std::deque<float> input, int numberOfBuffers) prefer const reference rather than creating a copy
of an object
const std::deque& input

Decimation in C++

Dear Stack Community,
I'm doing a DSP exercise to complement my C++ FIR lowpass filter with filter coefficients designed in and exported from Matlab. The DSP exercise in question is the act of decimating the output array of the FIR lowpass filter to a lower sample rate by a factor of 'M'. In C++ I made a successful but extremely simple implementation within a .cpp file and I've been trying hard to convert it to a function to which I can give the output array of the FIR filter. Here is the very basic version of the code:
int n = 0;
int length = 50;
int M = 12;
float array[length];
float array2[n];
for (int i = 0 ; i<length; i++) {
array[i] = std::rand();
}
for (int i = 0; i<length; i=i+M) {
array2[n++] = array[i];
}
for (int i = 0; i<n; i++) {
std::cout << i << " " << array2[i] << std::endl;
}
As you can see very simple. My attempt to convert this to a function using is unfortunately not working. Here is the function as is:
std::vector<float> decimated_array(int M,std::vector<float> arr){
size_t n_idx = 0;
std::vector<float> decimated(n_idx);
for (int i = 0; i<(int)arr.size(); i = i + M) {
decimated[n_idx++] = arr[i];
}
return decimated;
}
This produces a very common Xcode error of EXC_BAD_ACCESS when using this section of code in the .cpp file. The error occurs in the line 'decimated[n_idx++] = arr[i];' specifically:
int length = 50;
int M = 3;
std::vector<float> fct_array(length);
for (int i = 0 ; i<length; i++) {
fct_array[i] = std::rand();
}
FIR_LPF test;
std::vector<float> output;
output = test.decimated_array(M,fct_array);
I'm trying to understand what is incorrect with my application of or perhaps just my translation of the algorithm into a more general setting. Any help with this matter would be greatly appreciated and hopefully this is clear enough for the community to understand.
Regards, Vhaanzeit
The issue:
size_t n_idx = 0;
std::vector<float> decimated(n_idx);
You did not size the vector before you used it, thus you were invoking undefined behavior when assigning to element 0, 1, etc. of the decimated vector.
What you could have done is in the loop, call push_back:
std::vector<float> decimated_array(int M,std::vector<float> arr)
{
std::vector<float> decimated;
for (size_t i = 0; i < arr.size(); i = i + M) {
decimated.push_back(arr[i]);
}
return decimated;
}
The decimated vector starts out empty, but a new item is added with the push_back call.
Also, you should pass the arr vector by const reference, not by value.
std::vector<float> decimated_array(int M, const std::vector<float>& arr);
Passing by (const) reference does not invoke a copy.
Edit: Changed loop counter to correct type, thus not needing the cast.

vector.push_back() crashes

I have a problem while working with vectors of a class. I have tried whittling away at the code as much as possible, leaving me with the code below. Yet, after doing this, I still cannot figure out why my program is crashing. I come from a world of VBA and my C++ debugging skills are poor to say the least and I apologize for that up front. Any guidance to improve my ability here will be gladly accepted.
My class:
class Tester {
public:
int varA;
int varB;
Tester() {
varA = 1;
varB = 1;
}
Tester(Tester& P1, Tester& P2) {
varA = P1.varA + P2.varA;
varB = P1.varB + P2.varB;
}
Tester(const Tester &Source) {
varA = Source.varA;
varB = Source.varB;
}
};
My test mains:
Does not work:
int main() {
std::vector < Tester > BreakIt;
for (int i = 0; i < 2500; i++) {
Tester newTester;
BreakIt.push_back(newTester);
Tester& tempTester = BreakIt.at(0);
for (int j = 0; j < 4; j++) {
BreakIt.push_back(Tester(newTester, tempTester)); //This is where it crashes.
}
}
return 0;
}
Does work:
int main() {
std::vector < Tester > BreakIt;
Tester newTester;
BreakIt.push_back(newTester);
for (int i = 0; i < 2500; i++) {
Tester& tempTester = BreakIt.at(0);
for (int j = 0; j < 4; j++) {
BreakIt.push_back(Tester(newTester, tempTester));
}
}
return 0;
}
Does work:
int main() {
std::vector < Tester > BreakIt;
for (int i = 0; i < 2500; i++) {
Tester newTester;
BreakIt.push_back(newTester);
Tester& tempTester = BreakIt.at(0);
}
return 0;
}
The push_back() line that breaks does run a few times before the crash. It seems that when I change certain things around and recompile, the point at which it crashes changes (i.e. 20 times through the main loop vs. 175 times vs. 1000 times). However, once I've compiled, it will typically run through the the same iteration each time before crashing.
I suspect that this is some kind of 'undefined behavior' but from where I'm not sure.
Can someone please help me identify why BreakIt.push_back(Tester(newTester, tempTester)); does not work where I want it to?
You're right, there is undefined behaviour.
You're taking a reference to BreakIt.at(0); however this object is no longer guaranteed to exist after you've done a push_back, because if the vector grows, all of the contents are typically copied, and the originals deleted.
From http://www.cplusplus.com/reference/stl/vector/push_back/ (not the world's best reference):
Reallocations invalidate all previously obtained iterators, references and pointers.
For me, it was the issue with the MinGW version (MinGW g++ 6.3.0) which I updated to 7.2.0 from https://mingw-w64.org/doku.php/download.
Now it's working fine.