一个简单的c++程序中的分段故障

Segmentation fault in a simple C++ program

本文关键字:c++ 程序 分段 故障 简单 一个      更新时间:2023-10-16

程序给了我一个分段错误。我该如何解决这个问题?

我有makefile, fir_filter.cpp, fir_filter_mod.cpp, fir_filter.h, fir_filter_mod.htestbench.cpp。基本上我使用testbench来检查fir_filter.cppfir_filter_mod.cpp之间的结果。

Makefile文件:

CAT_HOME = $(MGC_HOME)
TARGET = my_tb
OBJECTS = fir_filter.o fir_filter_mod.o testbench.o
DEPENDS = fir_filter.h fir_filter_mod.h
INCLUDES = -I"$(CAT_HOME)/shared/include"
DEFINES =
CXX = /usr/bin/g++
CXXFLAGS = -g $(DEFINES) $(INCLUDES)
$(TARGET) : $(OBJECTS)
    $(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJECTS)
$(OBJECTS) : $(DEPENDS)
# Phony target to remove all objects and executables
.PHONY: clean
clean:
    rm -f *.o my_tb

文件shift_class.h

#ifndef __SHIFT_CLASS__
#define __SHIFT_CLASS__
template<typename dataType, int NUM_REGS>
class shift_class{
    private:
        dataType regs[NUM_REGS];
        bool en;
        bool sync_rst;
        bool ld;
        dataType *load_data;
    public:
        shift_class(): en(true), sync_rst(false), ld(false) {}
        shift_class(dataType din[NUM_REGS]):
            en(true), sync_rst(false), ld(false) {
                load_data = din;
        }
        void set_sync_rst(bool srst) {
            sync_rst = srst;
        }
        void load(bool load_in){
            ld = load_in;
        }
        void set_enable(bool enable) {
            en = enable;
        }
        void operator << (dataType din){
            SHIFT: for(int i = NUM_REGS - 1; i >= 0; i--) {
                if(en)
                    if(sync_rst)
                        regs[i] = 0;
                    else if(ld)
                        regs[i] = load_data[i];
                    else
                        if(i == 0)
                            regs[i] = din;
                        else
                            regs[i] = regs[i - 1];
            }
        }
        dataType operator [] (int i){
            return regs[i];
        }
};
#endif

文件fir_filter.h

void fir_filter(double *x, double *y);

文件fir_filter.cpp

#include "fir_filter.h"
#include "shift_class.h"
void fir_filter(double *x, double *y) {
    const double h[4] = {0.5, 0.5, 0.5, 0.5};
    static shift_class<double, 4> regs;
    double temp = 0;
    regs << *x;
    MAX: for(int i = 0; i < 4; i++) {
        temp += h[i] * regs[i];
    }
    *y = temp;
}

文件fir_filter_mod.cpp

#include "fir_filter_mod.h"
#include "shift_class.h"
double fir_filter_mod(double *x) {
    const double h[4] = {0.5, 0.5, 0.5, 0.5};
    static shift_class<double, 4> regs;
    double y = 0;
    double temp = 0;
    regs << *x;
    MAX: for(int i = 0; i < 4; i++) {
        temp += h[i] * regs[i];
    }
    y = temp;
    return y;
}

文件fir_filter.h

double fir_filter_mod(double *x);

文件testbench.cpp

#include <iostream>
#include "fir_filter.h"
#include "fir_filter_mod.h"
using namespace std;
int main()
{
    double *x;
    double *y;
    double y_mod;
    double init = 1;
    x = &init;
    for(int j = 0; j < 5; j++) {
        fir_filter(x, y);
        y_mod = fir_filter_mod(x);
        if(*y == y_mod) {
            cout << "ERROR" << endl;
        }
        else {
            cout << y_mod << endl;
        }
    }
}

坏主意:在程序中放入大量打印屏幕的代码。然后,您可以检查程序的最后一条消息,并尝试找到发生段错误的地方。您还可以打印调试数据,如不同变量的值。

好主意:使用调试器。它使坏主意的不必要实现。

另一个好主意:尝试对代码进行审计。有很多c++代码分析器。它们可以揭示程序中潜在的危险。

错误在这里:

 if(*y == y_mod) {
        cout << "ERROR" << endl;

在前面的步骤中,你调用了void fir_filter(double *x, double *y),它不会改变指针的值。但是你不会在程序开始时初始化y。所以y不指向任何地方,y的解除防御会导致程序崩溃。

这部分有一个问题

int main()
{
    double *x;
    double *y;
    double y_mod;
    double init = 1;
    x = &init;
    for(int j = 0; j < 5; j++) {
        fir_filter(x, y);

,因为对fir_filter的调用将把结果写入*y,但指针并不指向任何地方。

fir_filter.cpp这一行的分段错误

*y = temp;

因为y不指向任何地方。

如果你想获得那个值,只需返回它或使用reference.

您需要的是一个调试器。尝试在gdb中运行您的程序,看看崩溃发生在哪里:

`gdb my_tb`

输入run命令启动程序运行。您可以使用bt命令查看崩溃发生时的堆栈跟踪。