转换为Qt的C代码在执行时崩溃

时间:2018-06-05 00:03:58

标签: qt c++11

我是编程和Qt的初学者,但是喜欢这个框架我正试图提高我的技能并在其上编写我的C ++代码。我有一个编写Ricker小波代码然后绘制它的任务。 我把它划分为两个任务,首先让ricker代码工作,当它运行时,然后实现绘制它的方法,我将使用qcustomplot。 我从C获得了一个代码,我试图将其改编为Qt。虽然在编译期间没有出现任何错误,但在执行它时会崩溃,并显示以下消息:

  

传递给C运行时函数的参数无效。 C:/Users/Flavio/Documents/qtTest/build-ricker2-Desktop_Qt_5_11_0_MinGW_32bit-Debug/debug/ricker2.exe   退出代码255

我应该翻译的代码是:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
float *rickerwavelet(float fpeak, float dt, int *nwricker);
int main(int argc, char **argv)
{
    int i;
    float dt;
    float fpeak;

    float *wricker=NULL;
    int nwricker;

    fpeak = atof(argv[1]);
    dt = atof(argv[2]);

    wricker = rickerwavelet(fpeak, dt, &nwricker);

    /* show value of ricker wavelets */
    for (i=0; i<nwricker; i++)
        printf("%i. %3.5f \n", i, wricker[i]);

    free(wricker);
    return(1);
}

/* ricker wavelet function, return an array ricker wavelets */
float *rickerwavelet(float fpeak, float dt, int *nwricker)
{
    int i, k;
    int nw;
    int nc;
    float pi;
    float nw1, alpha, beta;
    float *wricker=NULL;

    pi = 3.141592653589793;
    nw1 = 2.2/fpeak/dt;
    nw = 2*floor(nw1/2)+1;
    nc = floor(nw/2);

    wricker = (float*) calloc (nw, sizeof(float));
    for (i=0; i<nw; i++)
    {
        k = i+1;
        alpha = (nc-k+1)fpeakdtpi;
        beta = pow(alpha, 2.0);
        wricker[i] = (1 - (beta2)) * exp(-beta);
    }

    (*nwricker) = nw;
    return(wricker);
}

我在Qt上写的代码是:

#include <QCoreApplication>
#include <qmath.h>
#include <stdio.h>
#include <stdlib.h>
#include <QDebug>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    int i,k,nw,nc;
    double *wricker=NULL;
    int nwricker = 60;
    int wavelet_freq = 30;
    int polarity=1;
    int sampling_rate=0.004;
    float nw1, alpha, beta;
    const double pi = 3.141592653589793238460;

    nw1 = 2.2/wavelet_freq/sampling_rate;
    nw = 2*floor(nw1/2)+1;
    nc = floor(nw/2);

    wricker = (double*)calloc (nw, sizeof(double));
    for (i=0; i<nw; i++)
    {
        k = i+1;
        alpha = (nc-k+1)wavelet_freqsampling_ratepi;
        beta = pow(alpha, 2.0);
        wricker[i] = polarity((1 - (beta2)) * exp(-beta));
    };
    /* show value of ricker wavelets */
    for (i=0; i<nwricker; i++)
    {
        qDebug()<<i<<wricker[i];
    };

    free(wricker);

    return a.exec();
}

分析表达

在时间t处具有峰值频率f的Ricker小波的幅度A如下计算:

A = (1-2 pi^2 f^2* t^2) e^{-pi^2* f^2* t^2}

它的py代码是:

import numpy as np
import matplotlib.pyplot as plt

def ricker(f, length=0.128, dt=0.001):
    t = np.arange(-length/2, (length-dt)/2, dt)
    y = (1.0 - 2.0*(np.pi2)(f2)(t2)) * np.exp(-(np.pi2)(f2)(t**2))
    return t, y

f = 25 # A low wavelength of 25 Hz
t, w = ricker(f)

看起来很简单。

有没有人知道我的代码有什么问题?

做一些调试我发现问题是在将向量传递给qDebug时,它会给出一条消息:

  

因为从操作中收到了一个信号,因此停止了   系统。信号名称:SIGSEGV SIGNAL MEANING:SEGMENTATION FAULT

我将搜索有关此信号含义的更多信息。我只使用qDebug打算在终端上显示数据,以确保计算有效。

提前致谢。

1 个答案:

答案 0 :(得分:2)

C ++更像是Python而不是C.尽管你的C代码特别令人费解,但它仍然不像C ++那么好。

甚至绘制数据的完整示例可以非常非常简单。如果那并没有显示C ++和Qt的综合能力,我几乎不知道会发生什么:)

screenshot of the example

wavelet-plot-50690312.pro文件

QT = charts
SOURCES = main.cpp

的main.cpp

// https://github.com/KubaO/stackoverflown/tree/master/questions/wavelet-plot-50690312
#include <QtCharts>
#include <cmath>

const double pi = 3.14159265358979323846;

QVector<QPointF> ricker(double f, double length = 2.0, double dt = 0.001) {
   size_t N = (length - dt/2.0)/dt;
   QVector<QPointF> w(N);
   for (size_t i = 0; i < N; ++i) {
      double t = -length/2 + i*dt;
      w[i].setX(t);
      w[i].setY((1.0 - 2*pi*pi*f*f*t*t) * exp(-pi*pi*f*f*t*t));
   }
   return w;
}

QLineSeries *rickerSeries(double f) {
   auto *series = new QLineSeries;
   series->setName(QStringLiteral("Ricker Wavelet for f=%1").arg(f, 2));
   series->replace(ricker(f));
   return series;
}

int main(int argc, char *argv[]) {
   QApplication app(argc, argv);
   QChartView view;
   view.chart()->addSeries(rickerSeries(1.0));
   view.chart()->addSeries(rickerSeries(2.0));
   view.chart()->createDefaultAxes();
   view.setMinimumSize(800, 600);
   view.show();
   return app.exec();
}

当然,这在C ++中看起来很不错。 C怎么样?让我们假装我们对Qt有一些C绑定。然后它可能如下所示:

// https://github.com/KubaO/stackoverflown/tree/master/questions/wavelet-plot-50690312/c-binding
#include "qc_binding.h"
#include <math.h>
#include <stddef.h>
#include <stdio.h>

const double pi = 3.14159265358979323846;

CQVector *ricker(double f, double length, double dt) {
   scope_enter();
   size_t N = (length - dt/2.0)/dt;
   CQVector *vector = CQVector_size_(CQ_, CQPointF_type(), N);
   CQPointF *const points = CQPointF_(CQVector_data_at(vector, 0));
   for (size_t i = 0; i < N; ++i) {
      double t = -length/2 + i*dt;
      points[i].x = t;
      points[i].y = (1.0 - 2*pi*pi*f*f*t*t) * exp(-pi*pi*f*f*t*t);
   }
   return scope_leave_ptr(vector);
}

CQLineSeries *rickerSeries(double f) {
   scope_enter();
   CQLineSeries *series = CQLineSeries_(CQ_);
   CQLineSeries_setName(series, CQString_asprintf(CQ_, "Ricker Wavelet for f=%.2f", f));
   CQLineSeries_replaceVector(series, ricker(f, 2.0, 0.001));
   return scope_leave_ptr(series);
}

int main(int argc, char *argv[]) {
   scope_enter();
   CQApplication *app = CQApplication_(CQ_, &argc, argv);
   CQChartView *view = CQChartView_(CQ_);
   CQChart *chart = CQChartView_getChart(view);
   CQChart_addLineSeries(chart, rickerSeries(1.0));
   CQChart_addLineSeries(chart, rickerSeries(2.0));
   CQChart_createDefaultAxes(chart);
   CQWidget *view_ = CQWidget_cast(view);
   CQWidget_setMinimumSize(view_, 800, 600);
   CQWidget_show(view_);
   return scope_leave_int(CQApplication_exec(app));
}

通过一些工作,可以制作一个与C ++一样易于使用的C绑定:跟踪范围,RAII工作,在需要时调用析构函数,不会破坏要返回的值等。

https://github.com/KubaO/stackoverflown/tree/master/questions/wavelet-plot-50690312/c-binding提供了执行上述代码所需的所有最小约束力。