cppcheck out of bounds when it's not - static-code-analysis

When setting the size of a std::array in a class definition using a static const as the size, cppcheck doesn't know how large the array is. So it thinks I'm out of bounds when I'm not
Doing a #define seems to solve the problem so this is an academic question.
class A
{
A() : myArr()
{
myArr[0]=100;
}
static const int SOMEVAL = 4;
std::array<double, SOMEVAL+1> myArr;
int getVal() { return myArr[1]; };
}
int main(void)
{
A myA;
myA.getVal();
}
Any thoughts?

This was a defect in cppcheck:
https://trac.cppcheck.net/ticket/9202
Which has been fixed in the 1.89 release:
https://trac.cppcheck.net/changeset/121093658d788126d5f94792c4ea00447fdbb979/

Related

can coroutine be used to solve stack overflow due to too deep recursive function call?

Has anyone tried to use coroutine to solve stack overflow caused by too deep recursive function call? according to the document on coroutines, the coroutine state will be saved on heap instead of on stack, which could have the potential to avoid the limitation imposed by the limited stack size and thus provide a way to solve the stack overflow issue in a generic way. i have tried with some code but it looks like the stack over flow issue persists. anyone has any tips/advice to share? or point me to some tutorial? thanks in advance.
// file main
#include "RecursiveCall.h"
// coroutine
static ReturnObject DoIntegration(Context& ctx, ReturnObject::promise_type* parent, double x_n)
{
double* dummyA = new double[(int)((x_n + 1) * 2)]; // an effort to prevent heap allocation from "optimized out"
co_await AwaitableBase(ctx, parent, x_n);
ctx._dummyVec.push_back(dummyA); // part of the effort to prevent heap allocation from "optimized out"
}
// caller
static double Invoke(Context& ctx, ReturnObject::promise_type* parent, double x_n)
{
auto ret = DoIntegration(ctx, parent, x_n);
std::coroutine_handle<ReturnObject::promise_type> h = ret._coroH;
auto p = h.promise();
while (!h.done())
{
if (p.AreChildrenReady())
{
h();
break;
}
}
return p._area;
}
bool AwaitableBase::await_suspend(std::coroutine_handle<PromiseType> h)
{
_promise = &h.promise();
if (_parent)
{
_parent->RegisterChild(h);
}
if (_x_n <= _ctx._b)
{
_promise->_x_n = 0.0;
_promise->_area = 0.0;
return false;
}
_promise->_area = GetArea(_x_n, _ctx._incr);
double newX = _x_n - _ctx._incr;
_promise->_x_n = newX;
double area = Invoke(_ctx, &h.promise(), newX);
//post calculation
_promise->_area += area;
return true;
}
double CallRecursive(double x0, double x_n, double incr)
{
Context ctx{ x0, incr };
return Invoke(ctx, nullptr, x_n);
}
int main()
{
double x0 = 0.0;
double x_n = 4.5;
double incr = 0.5; // no stackoveflow
//double incr = 0.0015; // stack oveflow
auto area = CallRecursive(x0, x_n, incr);
std::cout << "integrated result: " << area << "\n";
}
// file RecrusiveCall.h
#include <coroutine>
#include <exception>
#include <map>
#include <iostream>
#include <vector>
/* integration certainly can and should be done in a sequencial way in real world. but here is just use it as a simple example of recursive call, so the integration is implemented as a recursive function call and is done from high limit of x to the lower limit */
static double GetY(double x)
{
using CurvePoint = std::pair<double, double>;
constexpr CurvePoint curve[10] = { {0.0, 1.0}, {0.5, 1.2}, {1.0, 1.0}, {1.5, 1.2}, {2.0, 1.0},
{2.5, 1.2}, {3.0, 1.0}, {3.5, 1.2}, {4.0, 1.0}, {4.5, 1.2} };
if (x < curve[0].first || x > curve[9].first)
return 0.0;
CurvePoint newPoint;
const auto p1 = std::lower_bound(&curve[0], &curve[10], x, [](const auto& a, const auto& b) constexpr { return a.first < b; });
// check for special cases: first
const auto p0 = p1 - 1;
return (p1->second - p0->second) * (x - p0->first) / (p1->first - p0->first) + p0->second;
}
static double GetArea(double end, double incr)
{
return (GetY(end) + GetY(end - incr)) * 0.5 * incr;
}
struct Context
{
double _b; // lower limit of the integration range
double _incr; // increment steplength
std::vector<double*> _dummyVec; // effort to prevent heap allocation from being optimzed out
~Context()
{
for (auto p : _dummyVec)
delete p;
}
};
struct ReturnObject
{
struct promise_type
{
using Handle = std::coroutine_handle<promise_type>;
ReturnObject get_return_object() {
return { std::coroutine_handle<promise_type>::from_promise(*this) };
}
std::suspend_never initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void unhandled_exception() {}
void return_void() {}
void RegisterChild(Handle& childH)
{
_children.push_back(childH);
}
bool AreChildrenReady()
{
for (auto c : _children)
{
if (!c.done())
return false;
}
return true;
}
double GetValue() const { return _area; }
std::vector<Handle> _children;
double _area{ 0 };
double _x_n{ 0 };
};
ReturnObject(promise_type::Handle coro) : _coroH(coro)
{
}
operator std::coroutine_handle<promise_type>() const { return _coroH; }
// A coroutine_handle<promise_type> converts to coroutine_handle<>
operator std::coroutine_handle<>() const { return _coroH; }
std::coroutine_handle<promise_type> _coroH;
};
struct AwaitableBase
{
typedef Context Ctx;
using PromiseType = ReturnObject::promise_type; // todo: remove
bool await_ready()
{
return false;
}
bool await_suspend(std::coroutine_handle<PromiseType> h);
PromiseType* await_resume()
{
return _promise;
}
AwaitableBase(Ctx& ctx, PromiseType* parent, double x_n) : _ctx(ctx), _x_n(x_n), _parent(parent)
{
}
~AwaitableBase()
{
}
Ctx& _ctx;
PromiseType* _parent{ nullptr };
PromiseType* _promise{ nullptr };
double _x_n{ 0.0 };
};
no.
the coroutine's stack frame remains allocated. what's pushed to heap (as custom handle struct) is minimal register state plus struct data, to later resume the stack frame.
that is how you can access all local variables after resuming where you left off.

Storing derived classes in a vector of base class

I have seen several versions of my question, but I still cannot find an answer that works. I have defined a base class called TwoPort and two derived classes called Reflector and Waveguide as follows:
#include <vector>
class TwoPort
{
public:
TwoPort() { yeast = ywest = 0.0; }
~TwoPort() {}
double getyeast() { return yeast; }
double getywest() { return ywest; }
virtual void step(double xeast, double xwest);
protected:
double yeast;
double ywest;
};
class Reflector :
public TwoPort
{
public:
Reflector() { Gamma = 0.0; }
~Reflector() {}
void step(double xeast, double xwest) override;
void setReflection(double G) { Gamma = G; }
private:
double Gamma;
};
class Waveguide :
public TwoPort
{
public:
Waveguide() { oldest = 0; }
~Waveguide() {}
void step(double xeast, double xwest) override;
void setDelay(unsigned int delay);
private:
std::vector<double> eastBuffer, westBuffer;
unsigned int oldest;
};
My goal is to create a vector containing a mixture of Reflectors and Waveguides. Based on the answers to previous questions like mine, I have tried a number of approaches, but so far none have worked. For example:
int main()
{
std::vector<std::unique_ptr<TwoPort>> tpcascade;
tpcascade.emplace_back(new Reflector);
tpcascade.emplace_back(new Waveguide);
tpcascade.emplace_back(new Reflector);
tpcascade[0]->setRefection(0.25);
}
In this case, the compiler does not recognize the setReflection method. So I tried this:
int main()
{
std::vector<std::unique_ptr<TwoPort>> tpcascade;
auto ref = std::make_unique<Reflector>();
ref->setReflection(0.25);
tpcascade.emplace_back(ref);
}
In this case I can set the reflection but I get a lengthy and complex error message about the emplace statement.
Help!
Did some research and tried a variation on the second approach above:
int main()
{
std::vector<std::unique_ptr<TwoPort>> tpcascade;
auto ref = std::make_unique<Reflector>();
ref->setReflection(0.25);
tpcascade.push_back(std::move(ref));
}
Switching to shared_ptr seems to work too, and is a bit cleaner:
int main()
{
std::vector<std::shared_ptr<TwoPort>> tpcascade;
auto ref = std::make_shared<Reflector>();
ref->setReflection(0.25);
tpcascade.push_back(ref);
}
This also seems to work, but seems risky to me:
tpcascade.push_back(std::make_shared<Reflector>());
std::dynamic_pointer_cast<Reflector>(tpcascade[0])->setReflection(0.25);

Looking for Segmentation Fault in C script

Hi trying to learn C specifically how to use pointers.
I wrote this script to practice ideas I've learned, but it crashes with segmentation fault error.
Bit of research search suggests that I am trying to access something that I should not be accessing I think that is an uninitialized pointer but I can't find it.
#include <stdio.h>
struct IntItem {
struct IntItem* next;
int value;
};
struct IntList {
struct IntItem* head;
struct IntItem* tail;
};
void append_list(struct IntList* ls, int item){
struct IntItem* last = ls->tail;
struct IntItem addition = {NULL,item};
last->next = &addition;
ls->tail = &addition;
if (!ls->head) {
ls->head = &addition;
}
}
int sum(int x, int y){
return x + y;
}
int max(int x, int y){
return x*(x>y) + y*(y>x);
}
int reduce(struct IntList xs, int (*opy)(int, int)){
struct IntItem current = *xs.head;
int running = 0;
while (current.next) {
running = opy(running,current.value);
current = *current.next;
}
return running;
}
int main(void) {
struct IntList ls = {NULL, NULL};
printf("Start Script\n");
append_list(&ls, 1);
append_list(&ls, 2);
append_list(&ls, 3);
printf("List Complete\n");
printf("Sum: %i",reduce(ls,sum));
printf("Max: %i",reduce(ls,max));
return 0;
}
Hints:
When you call append_list(&ls, 1), then inside append_list, what is the value of last?
What does last->next = &addition do?
And for your next bug:
What happens to addition after append_list returns? What does that mean for pointers to it?

How to write a dummy network device driver

I'm trying to write a dummy network driver and have written the code, but I'm facing issue while trying to load driver i.e. it's crashing the kernel sometimes and sometimes it doesn't respond.
Dummy device code
#include <linux/module.h>
#include <linux/netdevice.h>
int virtualNIC_open(struct net_device *dev) {
printk("virtualNIC_open called\n");
netif_start_queue(dev);
return 0;
}
int virtualNIC_release(struct net_device *dev) {
printk("virtualNIC_release called\n");
netif_stop_queue(dev);
return 0;
}
int virtualNIC_xmit(struct sk_buff *skb, struct net_device *dev) {
printk("dummy xmit function called...\n");
dev_kfree_skb(skb);
return 0;
}
int virtualNIC_init(struct net_device *dev);
const struct net_device_ops my_netdev_ops = {
.ndo_init = virtualNIC_init,
.ndo_open = virtualNIC_open,
.ndo_stop = virtualNIC_release,
.ndo_start_xmit = virtualNIC_xmit,
};
int virtualNIC_init(struct net_device *dev) {
dev->netdev_ops = &my_netdev_ops;
printk("virtualNIC device initialized\n");
}
struct net_device virtualNIC = {
.netdev_ops = &my_netdev_ops,
/* .netdev_ops.ndo_init: virtualNIC_init*/
};
int virtualNIC_init_module(void) {
int result;
strcpy(virtualNIC.name, "virtualNIC");
if((result = register_netdev(&virtualNIC))) {
printk("virtualNIC: Error %d initalizing card ...", result);
return result;
}
return 0;
}
void virtualNIC_cleanup (void)
{
printk ("<0> Cleaning Up the Module\n");
unregister_netdev (&virtualNIC);
return;
}
module_init(virtualNIC_init_module);
module_exit(virtualNIC_cleanup);
MODULE_LICENSE("GPL");
Please help me to figure, where I'm going wrong.
Thanks in Advance
There is already network dummy codec in the mainline kernel. But still if you want to write for the practice. Then I think you can proceed with your own driver as well.
I have modified some of things in your driver. I think you can give one try to it see whether you can see the dummy interface in your ifconfig or not. It is just a sample code (for the interface entry in the ifconfig) and I am not handling any kind of locking or network packet transmission or reception.
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/kernel.h>
#include <linux/etherdevice.h>
struct net_device *virtualNIC;
int virtualNIC_open(struct net_device *dev) {
printk("virtualNIC_open called\n");
return 0;
}
int virtualNIC_release(struct net_device *dev) {
printk("virtualNIC_release called\n");
netif_stop_queue(dev);
return 0;
}
int virtualNIC_xmit(struct sk_buff *skb, struct net_device *dev) {
printk("dummy xmit function called...\n");
dev_kfree_skb(skb);
return 0;
}
const struct net_device_ops my_netdev_ops = {
.ndo_init = virtualNIC_init,
.ndo_open = virtualNIC_open,
.ndo_stop = virtualNIC_release,
.ndo_start_xmit = virtualNIC_xmit,
};
int virtualNIC_init(struct net_device *dev) {
printk("virtualNIC device initialized\n");
return 0;
};
static void virtual_setup(struct net_device *dev){
dev->netdev_ops = &my_netdev_ops;
}
int virtualNIC_init_module(void) {
int result;
virtualNIC = alloc_netdev(0, "virtnC%d", virtual_setup);
if((result = register_netdev(virtualNIC))) {
printk("virtualNIC: Error %d initalizing card ...", result);
return result;
}
return 0;
}
void virtualNIC_cleanup (void)
{
printk ("<0> Cleaning Up the Module\n");
unregister_netdev (virtualNIC);
}
module_init(virtualNIC_init_module);
module_exit(virtualNIC_cleanup);
MODULE_LICENSE("GPL");
This is very helpful, I just want to add this part of code:
virtualNIC = alloc_netdev (0, "virtnC%d", NET_NAME_UNKNOWN, virtual_setup);
this has 4 parameter in new kernel...

QT C++ wait till specific time to execute function

I am trying to create an app that holds a list of tasks and for each time a deadline, now i want to execute a function (show a popup) once a deadline is met.
i have this:
#ifndef TIMER_H
#define TIMER_H
#include <QWidget>
#include <QTimer>
#include <QtGui>
#include <QObject>
class Timer : public QWidget
{
Q_OBJECT
public:
Timer(QWidget * parent = 0);
void setTimer(QString title, QString description, QDate date, QTime reminderTime);
public slots:
void showWarning() {QString show = tit;
QPushButton * thanks = new QPushButton(QObject::tr("Thank you for reminding me!"));
show.append("\n");
show.append(des);
QMessageBox popup;
popup.setText(show);
popup.setWindowTitle("Calendar : Reminder");
popup.setDefaultButton(thanks);
popup.exec();
}
private:
QString tit;
QString des;
QDateTime now;
QDateTime timeoftheaction;
QTimer *timer;
};
cpp file:
#endif // TIMER_H
#include "timer.h"
#include <iostream>
using namespace std;
Timer::Timer(QWidget * parent)
: QWidget(parent)
{
}
void Timer::setTimer(QString title, QString description, QDate date, QTime reminderTime)
{
now.currentDateTime();
timer = new QTimer;
tit = title;
des = description;
timeoftheaction.setDate(date);
timeoftheaction.setTime(reminderTime);
connect(timer, SIGNAL(timeout()),this,SLOT(showWarning()));
timer->start(now.secsTo(timeoftheaction)*1000);
}
Yet function showWarning is never being called...
no compilation errors, function showWarning works perfectly (tested)
I think the error is in the connect but i am not sure...
Short answer:
Change:
now.currentDateTime();
to
now = QDateTime::currentDateTime();
Longish answer:
currentDateTime() is a static function which instead of changing your existing object, actually returns a new QDataTime object. Although you are calling it as a member function, it's still called as a static one and leaves your object intact, which is still invalid.
Your later call to secsTo() on an invalid data time probably gets you an negative or really large number that either has passed (never going to trigger) or really late in the future.
Here is something that might be a more generic solution.
#include <QThread>
#include <QTimer>
#include <QObject>
#include <map>
/**
* Singleton to implement simple 'relative' timer.
* Implements busy wait and also timeout-notifications (useful to monitor operations that could hang, etc).
*
* If the whole application is stalled (e.g. when a new device is connected), and we only want to
* wait for a period during which application was 'really' working (not just hanging waiting for OS)
* - then ticks will be missed too. This way - it's should be possible to avoid unnecessary timeouts
* that could happen if global time was measured (especially annoying on WINdows platforms)
*/
class RelativeTimer : public QObject
{
Q_OBJECT
typedef std::multimap <unsigned int, std::pair <QObject*, QString> > Notifications;
public:
/**
* Call to busy-wait for number of ticks.
*/
static void wait_num_of_ticks(unsigned int num_of_ticks_to_wait)
{
if(self.timer_id == 0)
{
qDebug("timer not initialised, call 'RelativeTimer::Init()'");
return;
}
if(num_of_ticks_to_wait > 0)
{
unsigned long until = self.tick_counter + num_of_ticks_to_wait; // it's ok if it wraps around..
while(self.tick_counter != until)
{
QCoreApplication::processEvents(); // let others to their job..
// or comment above out and just busy wait..
}
}
}
/**
* Call to busy-wait until ms_to_wait have elapsed.
* If ms_to_wait is < tick period
* Interval will define 'tick' frequency (and accuracy).
*/
static void wait_ms(unsigned int ms_to_wait)
{
wait_num_of_ticks(num_of_ticks_to_wait(ms_to_wait));
}
/**
* Call to schedule a notification after a given timeout.
* returns notification_id that can be used to cancel this notification.
*/
static unsigned long notify_timeout_ms(unsigned int ms_to_wait,
QObject *receiver,
const char* method_name)
{
unsigned long ticks_to_wait = 0;
if(receiver && method_name)
{
ticks_to_wait = num_of_ticks_to_wait(ms_to_wait);
if(ticks_to_wait > 1)
{
ticks_to_wait += self.tick_counter;
if(ticks_to_wait == 0) // avoid 0 - make it one tick more (to alow to see if successfully added this notif)
{
ticks_to_wait = 1;
}
self.notifications.insert(std::make_pair(ticks_to_wait,
std::make_pair(receiver, method_name)));
qDebug("added delayed call..");
}
else
{
QMetaObject::invokeMethod(receiver, method_name, Qt::QueuedConnection);
ticks_to_wait = 0;
}
}
return ticks_to_wait;
}
/**
* Call to cancel a notification with a given id.
* Specify name if there were more notification with the same id (scheduled for the same tick).
* returns true on successfull cancellation, false otherwise.
*/
static bool cancel_timeout_notification(unsigned long notification_id, QString notification_name="")
{
bool cancelled = false;
if(self.notifications.size())
{
std::pair<Notifications::iterator, Notifications::iterator> to_cancel = self.notifications.equal_range(notification_id);
Notifications::iterator n = to_cancel.first;
for( ;n != to_cancel.second; ++n)
{
if(notification_name.size()== 0 || n->second.second == notification_name)
{
self.notifications.erase(n);
cancelled = true;
break;
}
}
}
return cancelled;
}
static const unsigned int default_tick_period_ms = 100;
/**
* Call this method after event loop is created- to initiate (re-start) timer.
* tick period defines 'tick' frequency (and accuracy of the timer)
* (note on Windows that there's no point to go down below 100ms).
*/
static void Init(unsigned int tick_period_ms = default_tick_period_ms)
{
self.moveToThread(&self.thread);
self.thread.start();
while(!self.thread.isRunning());
self.current_interval = tick_period_ms;
// InitMe() should execute in the thread context..
QMetaObject::invokeMethod(&self, "InitMe", Qt::QueuedConnection);
}
private:
/**
* Internal method to convert ms to number of ticks.
*/
static unsigned int num_of_ticks_to_wait(unsigned int ms_to_wait)
{
if(ms_to_wait > self.current_interval)
{
if(ms_to_wait % self.current_interval)
{
// average it..
ms_to_wait = ms_to_wait + self.current_interval / 2;
}
ms_to_wait /= self.current_interval;
}
else
{
ms_to_wait = 0;
}
return ms_to_wait;
}
/**
* Internal method to handle tick. Increments counter and invokes notifications.
*/
void timerEvent ( QTimerEvent* /*event*/ )
{
tick_counter++;
if(notifications.size())
{
std::pair<Notifications::iterator, Notifications::iterator> to_notify = notifications.equal_range(tick_counter);
Notifications::iterator n = to_notify.first;
for( ;n != to_notify.second; ++n)
{
QMetaObject::invokeMethod(n->second.first,
n->second.second.toStdString().c_str(),
Qt::QueuedConnection);
}
notifications.erase(to_notify.first, to_notify.second);
}
}
private slots:
/**
* Internal slot to initialize the timer. Should be called in this->timer context.
*/
void InitMe()
{
if(timer_id != 0)
{
killTimer(timer_id);
timer_id = 0;
}
tick_counter = 0;
timer_id = self.startTimer(self.current_interval);
}
private:
RelativeTimer()
{
}
~RelativeTimer()
{
thread.quit();
thread.wait();
}
QThread thread;
Notifications notifications;
int timer_id;
unsigned int current_interval;
unsigned long tick_counter;
static RelativeTimer self; // implement it as a signleton.. Define it in your C file, e.g.:
// RelativeTimer RelativeTimer::self;
};
Can be used like:
CurrQObjectClass::OnTimeout()
{
// ...
}
CurrQObjectClass::SomeMethod()
{
RelativeTimer::notify_timeout_ms(5000, this, "OnTimeout");
}
but also for busy-waiting:
RelativeTimer::wait_ms(2000);
Enjoy.

Resources