You can see commit history by clicking the commits link:
You copy the SHA of the commit you want to revert to, open a terminal, go to source folder and type
git reset --hard <SHA>
C++ and MATLAB Simulink tips for HWIL simulation software engineers
You can see commit history by clicking the commits link:
git reset --hard <SHA>
Dynamically creating array of object on the heap:
MyClass** objects;
arrSize = 100;
objects = new MyClass*[arrSize]; //Note the '*' before arrSize
for (size_t i = 0; i < arrSize; i++) {
objects[i] = new MyClass();
}
Freeing up heap memory allocated to object array:
for (size_t i = 0; i < arrSize; i++) {
delete objects[i];
}
delete[] objects;
Tip: You can use Visual Studio's Memory Usage diagnostic tool to check heap memory changes which gives clues about memory leaks. To get the function names where memory is allocated but then never released, use valgrind on WSL (Linux) as follows:
valgrind --tool=memcheck --leak-check=yes ./<app name>
You can use Windows 10 and Visual Studio 2022 to generate, debug and analyze Linux binaries:
The following C++ code demonstrates how to safely use an array that is written to by one thread and read from in another thread:
//How to safely use an array that is written to by one thread and read from in another thread. | |
//Requires C++11 or later. | |
//Şamil Korkmaz, 10.03.2022, public domain. | |
#include <chrono> | |
#include <iostream> | |
#include <thread> | |
#include <mutex> | |
std::mutex mx; | |
std::condition_variable cv; | |
const size_t arraySize = 1000; | |
double arr[arraySize]; | |
void writeArray() { | |
size_t counter = 0; | |
while (1) { | |
auto currentTime = std::chrono::steady_clock::now(); | |
auto nextTime = currentTime + std::chrono::milliseconds(1); | |
//printf("writeArray, counter = %d\n", counter); | |
{ //critical section | |
std::unique_lock<std::mutex> lock(mx); | |
for (size_t i = 0; i < arraySize; i++) { | |
arr[i] = counter; | |
} | |
} //lock is automatically released here | |
cv.notify_all(); //let other threads to get lock | |
counter++; | |
std::this_thread::sleep_until(nextTime); | |
} | |
} | |
void readArray() { | |
while (1) { | |
auto currentTime = std::chrono::steady_clock::now(); | |
auto nextTime = currentTime + std::chrono::milliseconds(1); | |
double arrStart; | |
double arrEnd; | |
{ //critical section | |
std::unique_lock<std::mutex> lock(mx); | |
cv.wait(lock); //wait for writeArray to finish | |
arrStart = arr[0]; | |
arrEnd = arr[arraySize - 1]; | |
} //lock is automatically released here | |
auto arrDiff = arrEnd - arrStart; | |
printf("* readArray, arrStart = %1.0f, arrEnd = %1.0f, arrDiff = %1.1f\n", arrStart, arrEnd, arrDiff); | |
if (arrDiff < 0) //happens when the end of array is lagging behing beginning of array. You trigger it by commenting out the lock line above | |
{ | |
printf("End of array lagging behind beginning of array! arrDiff = %1.1f < 0\n", arrDiff); | |
std::cout << "Press enter..." << std::endl; | |
std::cin.get(); | |
exit(1); | |
} | |
std::this_thread::sleep_until(nextTime); | |
} | |
} | |
int main() { | |
std::thread worker1(writeArray); | |
std::thread worker2(readArray); | |
worker1.join(); | |
worker2.join(); | |
std::cout << "Press enter..." << std::endl; | |
std::cin.get(); | |
} |
You could define a custom class that derives from JFormattedTextField and use KeyListener to get the raw text that the user is typing:
public class MyFormattedTextField extends JFormattedTextField { | |
private String rawText; | |
private class MyKeyListener implements KeyListener { | |
... | |
@Override | |
public void keyTyped(KeyEvent e) { | |
rawText = getText(); | |
} | |
} | |
public MyFormattedTextField() { | |
addKeyListener(new MyKeyListener()); | |
} | |
public String getRawText() { | |
return rawText; | |
} | |
} |