Apparent method call after destruction in olcSoundMaker.h - c++

I couldn't come up with a better title, so feel free to give suggestions.
I tried to follow OneLoneCoder's tutorial on sound synthesizing, I'm only halfway through the first video and my code already throws an exception.
All I did was downloading his olcSoundMaker.h from his github, and copying the entry point:
#include <iostream>
#include "olcNoiseMaker.h"
double make_noise(double time)
{
return 0.5 * sin(440.0 * 2 * PI * time);
}
int main()
{
std::wcout << "Synthesizer, part 1" << std::endl;
std::vector<std::wstring> devices = olcNoiseMaker<short>::Enumerate();
for (auto d : devices)
{
std::wcout << "Found output device: " << d << std::endl;
}
olcNoiseMaker<short> sound(devices[0], 44100, 1, 8, 512);
sound.SetUserFunction(make_noise);
while (1) { ; }
return EXIT_SUCCESS;
}
In the video he runs this just fine; for me, it starts producing a sound, then after 60-80 iterations of the while (1) loop, it stops and raises this:
Unhandled exception thrown: write access violation.
std::_Atomic_address_as<long,std::_Atomic_padded<unsigned int> >(...) was 0xB314F7CC.
(from the <atomic> header file, line 1474.)
By stepping through the code with VS I didn't find out much, except that it happens at different times during every run, which may mean it has something to do with multithreading, but I'm not sure since I'm not very familiar with the topic.
I found this question which is similar, but even though it says [SOLVED] it doesn't show me the answers.
Anyone that can help to get rid of that exception?

Related

Severe & Bizzare performance issue

Update
Ok, I removed the 3 couts and replaced it with *buffer = 'a', and there was a big performance difference. Removing that line made the program 2x as fast. If you go on godbolt and compile it using msvc, that single line of code changes most of the program. (It adds a whole lot more complexity)
The following might seem extremely weird, but it's true on my computer:
Alright, so I was doing some benchmarking of some code, and I noticed extremely weird performance anomalies that were 100% consistent. I'm running windows-10 and visual-studio-2019. Basically, deleting a line of code that is never called completely changes the performance of the program.
Here is exactly what to do:
Create new VS-2019 Console C++ App project
Set the configuration to Release & x64
Paste the code below:
#include <iostream>
#include <chrono>
class Test {
public:
size_t length;
size_t doublingVal;
char* buffer;
Test() : length(0), doublingVal(2) {
buffer = static_cast<char*>(malloc(1));
}
~Test() {
std::cout << "called" << "\n";
std::cout << "called" << "\n";
std::cout << "called" << "\n"; // Remove this line and the time decreases DRASTICALLY (ie remove line 14)
}
void append() {
if (doublingVal == length) {
doublingVal <<= 1;
}
*buffer = 'a';
++length;
}
};
int main()
{
Test test;
auto start = std::chrono::high_resolution_clock::now();
for (size_t i = 0; i < static_cast<size_t>(1024) * 1024 * 1024 * 4; ++i) {
test.append();
}
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start).count() << "\n";
}
Run the program using CTRL+F5, not in debug. Now remember how long it takes to run. (a few seconds)
Then, in the destructor of Test, remove the third line which has the comment.
Run the program again, and you should see that the performance increases drastically. I tested this exact same code with 4 different projects all brand new, and 3 different computers.
The destructor is called at the very end, when the entire program is finished measuring time. The extra cout shouldn't affect anything.
Edit:
You can also see a similar thing go on if you remove the 3 cout's and replace it with a single *buffer = 'a'. Then CTRL+F5 once again, record the time, and then remove that line we just added. Then run it again and the time magically decreases by half.
WTF is going on, and how do you solve the weird performance difference?

C++ condition variable with no time out

Recently, I met a problem which is related with condition variable in C++. The code is shown below :
#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
std::condition_variable cv;
std::mutex mutex;
int main(){
std::unique_lock<std::mutex> uniqueLock(mutex);
while (true)
{
if(cv.wait_for(uniqueLock, std::chrono::milliseconds(1000)) == std::cv_status::no_timeout)
{
std::cout << "has image" << std::endl;
}
else
{
std::cout<< "time out " << std::endl;
}
}
return 0;
}
The goal of this code is that : each time when condition variable is notified in another thread (cv.notify()), it show "has image " in the console, and if it can not be notified more than 1000 milliseconds, it shows "time out".
So the theoretical output of the above code is (because the condition variable is not notified) :
time out
time out
time out
time out
But when i execute this code in the Vs2015, I found that the output is strange:
has image
time out
has image
time out
time out
time out
has image
has image
time out
time out
time out
time out
time out
has image
has image
I would like to know why i have this output and how can i achieve my goal
Thanks !
I don't know what the cause of your error is (but there are some plausible explanations in the comments). However, one way to fix your issue is to use the other overload of wait_for, which includes a predicate.
It could look something like this (hasImage is just a bool here, replace it with something that makes sense for your needs - !imageStorage.empty() or similar):
while (true)
{
if (cv.wait_for(uniqueLock, std::chrono::milliseconds(1000), []() {return hasImage;}))
{
std::cout << "has image" << std::endl;
hasImage = false;
}
else
{
std::cout << "time out " << std::endl;
}
}
The pertinent point is that the predicate checks if there actually is a new image, and if there isn't then it should continue to wait.
One limitation with this method is that, if the predicate returns false (no image), then you don't know if the condition variable woke due to a spurious wakeup, a timeout, or if there actually was an image but another thread just took it away before this one woke up. But if that is something your design can handle, then this variation works very well.

How to use boost::async_system?

I am quite new to boost, as well as to multithreading and launching application using libraries. For my desired funcitonality, I was recommended by colleague to use boost::process library.
But the documentation to this part of boost is quite insufficient, so I could not determine which function suits my task best by documentation. I therefore started to try several functions there, but non has all the desired properties.
However there is one I cannot figure out, how to properly use. I cannot even compile it, let alone run it. And the function is boost::process::async_system. I could not find anywhere on internet some step-by-step guide on how to use this function and what individual components mean and do.
Could someone explain to me in detail the individual arguments and template arguments of the function ? Or provide a link to a detailed manual?
I like the examples here: https://theboostcpplibraries.com/boost.thread-futures-and-promises
For example, look at example 44.16, they clearly show how to use async:
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
#include <iostream>
int accumulate()
{
int sum = 0;
for (int i = 0; i < 5; ++i)
sum += i;
return sum;
}
int main()
{
boost::future<int> f = boost::async(accumulate);
std::cout << f.get() << '\n';
}
Waiting happens at the get method, not before. You might use a non-waiting mechanism, too.
As for compiling, you need to first build boost. Building is explained in detail here: https://www.boost.org/doc/libs/1_62_0/more/getting_started/windows.html
Most parts of the library work header-only. For asio, building the binary libraries (also explained in the link) is necessary. In your project (i.e. visual studio projects, xcode project or just some make files), you need to set include and library headers of boost to use it. The link above helps with this as well.
I'm just ramping up on Boost.Process but the sample code I have working might be helpful here.
boost::process:async_system() takes 3 parameters: a boost::asio::io_context object, an exit-handler function, and the command you want to run (just like system(), and it can be either a single line or more than one arg).
After it's invoked, you use the io_context object from the calling thread to manage and monitor the async task - I use the run_one() method which will "Run the io_context object's event processing loop to execute at most one handler" but you can also use other methods to run for a duration etc.
Here's my working code:
#include <boost/process.hpp>
#include <iostream>
using namespace boost;
namespace {
// declare exit handler function
void _exitHandler(boost::system::error_code err, int rc) {
std::cout << "DEBUG async exit error code: "
<< err << " rc: " << rc <<std::endl;
}
}
int main() {
// create the io_context
asio::io_context ioctx;
// call async_system
process::async_system(ioctx, _exitHandler, "ls /usr/local/bin");
std::cout << "just called 'ls /usr/local/bin', async" << std::endl;
int breakout = 0; // safety for weirdness
do {
std::cout << " - checking to see if it stopped..." << std::endl;
if (ioctx.stopped()) {
std::cout << " * it stopped!" << std::endl;
break;
} else {
std::cout << " + calling io_context.run_one()..." << std::endl;
ioctx.run_one();
}
++breakout;
} while (breakout < 1000);
return 0;
}
The only thing my example lacks is how to use boost::asio::async_result to capture the result - the samples I've see (including here on slashdot) still don't make much sense to me, but hopefully this much is helpful.
Here's the output of the above on my system:
just called 'ls /usr/local/bin', async
- checking to see if it stopped...
+ calling io_context.run_one()...
- checking to see if it stopped...
+ calling io_context.run_one()...
VBoxAutostart easy_install pybot
VBoxBalloonCtrl easy_install-2.7 pyi-archive_viewer
((omitted - a bunch more files from the ls -l command))
DEBUG async exit error code: system:0 rc: 0
- checking to see if it stopped...
* it stopped!
Program ended with exit code: 0

Memory leak using a class method

I have a problem with my program : I have a memory leak. I know it because when I look at the memory usage it never stop increasing, and then the program crash.
I have remarked that it happens because of this line (when I comment it there is no problem) :
replica[n].SetTempId(i+1); // FUITE MEMOIRE SUR CETTE LIGNE !!
I have checked that n is never bigger than the size of my array (which is a vector type, see below).
My class :
class Replica
{
/* All the functions in this class are in the 'public:' section */
public:
Replica();
~Replica();
void SetEnergy(double E);
void SetConfName(string config_name);
void SetTempId(int id_temp);
int GetTempId();
string GetConfName();
double GetEnergy();
void SetUp();
void SetDown();
void SetZero();
int GetUpDown();
/* All the attributes in this class are in the 'private:' section */
private:
double m_E; // The energy of the replica
string m_config_name; // The name of the config file associated
int m_id_temp; // The id of the temperature where the spin configuration is.
int m_updown;
};
The method
void Replica::SetTempId(int id_temp)
{
m_id_temp=id_temp;
}
I initialised my object like this :
vector<Replica> replica(n_temp); // we create a table that will contain information on the replicas.
The constructor :
Replica::Replica() : m_E(0), m_config_name(""), m_updown(0), m_id_temp(0)
{
}
How I initialize my vector :
for(int i=0; i<=n_temp-1 ; i++) // We write the object replica that will contain information on a given spin configuration.
{
string temp_folder="";
temp_folder= spin_folder + "/T=" + to_string(Tf[i]) + ".dat";
replica[i].SetEnergy(Ef[i]+i); // we save the energy of the config (to avoid to calculate it)
replica[i].SetConfName(temp_folder); // we save the name of the file where the config is saved (to avoid to have huge variables that will slow down the program)
replica[i].SetTempId(i);
replica[i].SetZero();
if(i==0)
replica[i].SetDown();
if(i==(n_temp-1))
replica[i].SetUp();
}
I am a beginner in C++ so it is probably a basic mistake.
Thank you for your help !
I have read your answers.
But it is hard to write a minimal code : I tried to delete some stuff but as soon as I delete lines it works.
In fact the problem is very "random", for example when I delete my line :
replica[n].SetTempId(i+1);
it works, but I can have this line not deleted but when I delete an other line of my code it will also works (I dont know if you see what I mean).
The bug is very hard to find because of this "randomness"...
I also can say that when it crash the program says me :
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
So, could you give me guess on what could cause this error (because I don't arrive to write the minimal code).
I don't do dynamic allocation on my code.
The structure of my code is like this :
while(Nsw_c<Nsw)
{
cout << "test1";
// a
// lot
// of
// code
// with some Nsw_c++
// and this cout at the end of the loop
cout << " Nsw_c : " << Nsw_c << endl << " i " << i << " compteur_bug " << compteur_bug;
}
cout << "test2";
It ALWAYS freeze on this cout above which is at the end of the loop.
I know this because neither test2 or test1 are displayed when it freezes and it is the next cout.
Nsw, Nsw_c, i are integers that are lower than 100 (they are not too big).
To be more precise, if I replace the cout just at the end of the loop by another cout like this :
cout << " test ";
It will also freeze at the same place.
In fact the program always freeze at the end of my while (juste before analysing the condition).
But Nsw and Nsw_c are not big at all so that's why it is strange.
I tried to replace the condition Nsw_c < Nsw just by "1" and it didn't freeze anymore. So it is probably a problem with the condition but both are just "normal" integers so...
Thanks !
I have launched gdb (i just learnt to use it) and i wrote :
catch throw std::bad_alloc
The debugger then do this (I don't know if it can help) :
not stopped at a C++ exception catchpoint
Catchpoint 1 (exception thrown), 0xb7f25290 in __cxa_throw () from /usr/lib/i386-linux-gnu/libstdc++.so.6

semop() failing at failing

I'm trying to write a program in C++, compiled in GCC 4.6.1 on Ubuntu 11.10, and the IPC is giving me a hard time. To demonstrate, here's my code for signaling a semaphore, with semid and semnum already supplied:
struct sembuf x;
x.sem_num = semnum;
x.sem_op = 1;
x.sem_flg = SEM_UNDO;
int old_value = semctl(semid, 0, GETVAL);
if(semop(semid, &x, 1) < 0)
{
std::cerr << "semaphore failed to signal" << std::endl;
}
else if(semctl(semid, 0, GETVAL) == old_value)
{
std::cerr << "signal returned OK, but didn't work" << std::endl;
}
The code for "wait" is similar; the main difference, of course, is that sem_op is set to -1. Sometimes I get the first error message here, but as often as not I get the second, which makes no sense at all to me. The first, I imagine I could hunt for an error code (though I'm not sure if that depends on C++11 features I'm not supposed to use), but I've got no idea how to even begin addressing the second. Rebooting didn't work. GDB isn't being much help, especially when "next" and "step" seem to jump around back and forth instead of going forward in sequence.