不能理解这个SEGFAULT

can not understand this SEGFAULT

本文关键字:SEGFAULT 能理解 不能      更新时间:2023-10-16

我正在编程一个在linux、windows上工作的c/c++SDL合成器,它处理psp,我在代码的多个部分中混合了c/c++。我使用新的malloc,我不认为我混淆了它们,但如果我混淆了,请告诉我在哪里以及为什么。

我的主程序现在接近20000行,运行良好。但当我开始修改它时,我总是陷入一个错误,我无法理解和发现我真正的错误。

当我开始修改代码的某些部分时,我陷入了SIGSEV,我花了几个小时才使其工作,但我不明白为什么会陷入这种境地。经过一些修改后,它又能工作了,我不知道为什么我有一个SIGSEV,为什么它现在被修复了,以及我如何修改它以使它工作并防止未来的错误。所以我请你解释一下我真正的错误是什么。

这是一个gdb日志,有一个真正的精简版本和我遇到的那种崩溃:

    yoyz@yoyz-laptop:~/build/audio/picoloop/tmp/ gdb ./WaveTable 
    GNU gdb (GDB) 7.4.1-debian
    Copyright (C) 2012 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later         <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show         copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-linux-gnu".
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>...
    Reading symbols from         /home/yoyz/build/audio/picoloop/tmp/WaveTable...done.
    (gdb) r
    Starting program: /home/yoyz/build/audio/picoloop/tmp/WaveTable 
    warning: the debug information found in "/lib64/ld-2.13.so" does not         match "/lib64/ld-linux-x86-64.so.2" (CRC mismatch).
    Generator::init() Allocating memory
    Generator::one() 0x00604010
    Generator::sine() 0x00604010
    Generator::saw() 0x00604010
    Generator::pulse() 0x00604010
    Program received signal SIGSEGV, Segmentation fault.
    _int_malloc (av=0x7ffff7639e40, bytes=32768) at malloc.c:4738
    4738    malloc.c: No such file or directory.
    (gdb) 

这是代码的精简版本:

    #include "MyMaster.h"
    #include "Generator.h"
    #include "WaveTable.h"
    #include "WaveTableManager.h"

    int main(int argc,char **argv)
    {
      Generator G;
      WaveTableManager & WTM = WaveTableManager::getInstance();
      WaveTable* WT;
      G.init();

      WT = new WaveTable();
      WT->setSize(WAVETABLE_SIZE);
      G.one();
      memcpy(WT->getBuffer(),G.getBuffer(),WAVETABLE_SIZE*DEFAULTBITRATE/8);
      WTM.insert(WT,PICO_WAVETABLE_ONE);

      WT = new WaveTable();
      WT->setSize(WAVETABLE_SIZE);
      G.sine();
      memcpy(WT->getBuffer(),G.getBuffer(),WAVETABLE_SIZE*DEFAULTBITRATE/8);
      WTM.insert(WT,PICO_WAVETABLE_SINE);

      WT = new WaveTable();
      WT->setSize(WAVETABLE_SIZE);
      G.saw();
      memcpy(WT->getBuffer(),G.getBuffer(),WAVETABLE_SIZE*DEFAULTBITRATE/8);
      WTM.insert(WT,PICO_WAVETABLE_SAW);

      WT = new WaveTable();
      WT->setSize(WAVETABLE_SIZE);
      G.pulse();
      memcpy(WT->getBuffer(),G.getBuffer(),WAVETABLE_SIZE*DEFAULTBITRATE/8);
      WTM.insert(WT,PICO_WAVETABLE_PULSE);

      WT = new WaveTable();
      WT->setSize(WAVETABLE_SIZE);
      G.triangle();
      memcpy(WT->getBuffer(),G.getBuffer(),WAVETABLE_SIZE*DEFAULTBITRATE/8);
      WTM.insert(WT,PICO_WAVETABLE_TRGL);

      WT = new WaveTable();
      WT->setSize(WAVETABLE_SIZE);
      G.noise();
      memcpy(WT->getBuffer(),G.getBuffer(),WAVETABLE_SIZE*DEFAULTBITRATE/8);
      WTM.insert(WT,PICO_WAVETABLE_NOISE);

      printf("wavetablemanager.getSize : %dn",WTM.getSize());
    }

MyMaster.h

    #ifndef __MASTER____
    #define __MASTER____
    #include <SDL/SDL.h>
    #define WAVETABLE_SIZE  1024*16
    #define DEFAULTBITRATE   16
    enum 
      {
        PICO_WAVETABLE_SINE,
        PICO_WAVETABLE_SAW,
        PICO_WAVETABLE_PULSE,
        PICO_WAVETABLE_TRGL,
        PICO_WAVETABLE_NOISE,
        PICO_WAVETABLE_ONE,
        PICO_WAVETABLE_SIZE
      };
    #endif

发电机.h

    using namespace std;
    #include <SDL/SDL_types.h>
    #include <math.h>
    #include "MyMaster.h"
    #ifndef __GENERATOR__
    #define __GENERATOR__
    class Generator 
    {
    public:
      Generator();
      ~Generator();
      void init();
      void sine();
      void saw();
      void pulse();
      void triangle();
      void noise();
      void one();
      Sint16 * getBuffer();
     private:
      Sint16 * table;
      int      table_size;
      int      index;
      int      d;
    };
    #endif

发电机.cpp

    #include "Generator.h"
    Generator::Generator()
    {
      table_size=WAVETABLE_SIZE;
    }
    Generator::~Generator()
    {
    }
    void Generator::init()
    {
      if (table_size>0)
        {
          printf("Generator::init() Allocating memoryn");
          table=(Sint16*)malloc(sizeof(Sint16)*table_size);
          if (table==0)
            {
              printf("Error allocating memoryn");
              //return 0;
            } 
        }   
    }   
    void Generator::sine()
    {
      int i;
      float f;
      Sint16 s;
      Sint16 bitdepth=16-1;
      printf("Generator::sine() 0x%08.8Xn",table);
      for (i=0;i<table_size;i++)
        {
          s=sin((2*3.14159*i*1)/table_size)*(1<<bitdepth-2);
          table[i]=s;
          //printf("table[%d]=%dn",i,s);
        }
    }
    void Generator::saw()
    {
      int i;
      float f;
      Sint16 s;
      Sint16 bitdepth=16;
      Sint16 dec;
      printf("Generator::saw() 0x%08.8Xn",table);
      s=(1<<(bitdepth-2));
      dec=(1<<(bitdepth-2))/(table_size/2);
      for (i=0;i<table_size;i++)
        {
          table[i]=s;
          s=s-dec;
        }
    }
    void Generator::pulse()
    {
      int i;
      float f;
      Sint16 s;
      Sint16 bitdepth=16;
      Sint16 dec=(1<<(bitdepth-2))/(table_size/2);
      printf("Generator::pulse() 0x%08.8Xn",table);
      for (i=0;i<table_size/2;i++)
        {
          table[i]=((1<<(bitdepth-2))/2);
        }
      for (i=table_size/2;i<table_size;i++)
        {
          table[i]=((1<<(bitdepth-2))*-1)/2;
        }
    }
    void Generator::triangle()
    {
      int i;
      float f;
      Sint16 s=0;
      Sint16 bitdepth=16;
      Sint16 dec=(1<<(bitdepth-2))/(table_size/4);
      printf("Generator::triangle() 0x%08.8Xn",table);
      //table=(Sint16*)malloc(sizeof(Sint16)*table_size);
      for (i=0;i<(table_size*1)/4;i++)
        {
          table[i]=s;
          s=s+dec;
        }
      for (i=(table_size*1)/4;i<(table_size*3)/4;i++)
        {
          table[i]=s;
          s=s-dec;
        }
      for (i=(table_size*3)/4;i<table_size;i++)  
        {
          table[i]=s;
          s=s+dec;
        }
    }

    void Generator::noise()
    {
      int i;
      float f;
      Sint16 s;
      Sint16 bitdepth=16;
      printf("Generator::noise() 0x%08.8Xn",table);
      srand(1<<(bitdepth-2));
      for (i=0;i<table_size;i++)
        {
          if (rand()%2==0)
            table[i]=rand()%8192;
          else
            table[i]=(rand()%8192)*-1;
        }
    }
    void Generator::one()
    {
      int i;
      float f;
      Sint16 s;
      Sint16 bitdepth=16;
      printf("Generator::one() 0x%08.8Xn",table);
      for (i=0;i<table_size;i++)
        {
          table[i]=1<<bitdepth-1;
        }
    }

    Sint16 * Generator::getBuffer()
    {
      return table;
    }

WaveTable.h

    #include "MyMaster.h"
    #include <SDL/SDL_types.h>
    #ifndef __WAVETABLE__
    #define __WAVETABLE__
    class WaveTable
    {
     public:
      WaveTable();
      ~WaveTable();
       int      setSize(int bufferSize); 
       int      allocMemory();
       int      freeMemory(); 

      Sint16 * getBuffer();
      char   * getName();
      Sint32   getSize();

     private:
      Sint32   size;
      Sint16 * buffer;
      char   * name;
    };
    #endif

WaveTable.cpp

    #include "WaveTable.h"
    using namespace std;
    WaveTable::WaveTable()
    {
      size=0;
      buffer=0;
      name=0;
    }
    WaveTable::~WaveTable()
    {
    }

    int WaveTable::allocMemory()
    {
      if (size>0)
        {
          buffer=(Sint16*)malloc(sizeof(Sint16)*size);
          if (buffer==0)
            {
              printf("Error allocating memoryn");
              return 0;
            }
        }
      return size;
    }

    int WaveTable::freeMemory()
    {
      if (buffer!=0)
        {
          free(buffer);
          buffer=0;
        }
    }
    int WaveTable::setSize(int bufferSize)
    {
      if (bufferSize>=0)
        size=bufferSize;
      if (buffer!=0)
        this->freeMemory();
      return this->allocMemory();
    }
    Sint16 * WaveTable::getBuffer()
    {
      return buffer;
    }

WaveTableManager.h

    using namespace std;
    #include <vector>
    #include "WaveTable.h"
    #ifndef __WAVETABLEMANAGER__
    #define __WAVETABLEMANAGER__
    class WaveTableManager 
    {
    private:
      WaveTableManager();
      ~WaveTableManager();
      vector<WaveTable*> wtvector;  
      int    size;

    public:
      static WaveTableManager& getInstance();
      int         getSize();
      void        insert(WaveTable * WT,int position);
      WaveTable * get(int position);

    };
    #endif

WaveTableManager.cpp

    #include "WaveTableManager.h"
    WaveTableManager::WaveTableManager() : wtvector()
    {
      size=0;
    }

    WaveTableManager::~WaveTableManager()
    {
    }

    WaveTableManager& WaveTableManager::getInstance()
    {
      static WaveTableManager instance;
      return instance;
    }

    int WaveTableManager::getSize()
    {
      return wtvector.size();
    }
    void WaveTableManager::insert(WaveTable * WT,int position)
    {
      if (wtvector.size()<=position)
        wtvector.resize(position);
      wtvector[position]=WT;
    }

    WaveTable * WaveTableManager::get(int position)
    {
      return wtvector[position];
    }

Makefile.WaveTable

    CC=g++
    CFLAGS=-O0 -DLINUX -D__RTAUDIO__ -DLINUX_DESKTOP -I. -LSDL/lib -g -fpermissive
    SOURCES=WaveTableTest.cpp WaveTable.cpp WaveTableManager.cpp Generator.cpp
    OBJECTS=$(SOURCES:.cpp=.o)
    EXECUTABLE=WaveTable
    all: $(SOURCES) $(EXECUTABLE)
    $(EXECUTABLE): $(OBJECTS)
            $(CC) $(LDFLAGS) $(OBJECTS) -o $@
    .cpp.o:
            $(CC) -c $(CFLAGS) $< -o $@
    clean:
            -rm -f $(OBJECTS) $(EXECUTABLE)

这里有一个问题:

void WaveTableManager::insert(WaveTable * WT,int position)
{
  if (wtvector.size()<=position)
    wtvector.resize(position);
  wtvector[position]=WT;  // < -- Out of bounds access
}

当您调用resize()时,上限为vector::size()-1。由于position是矢量的新大小,您可能想要的是:

  wtvector[position - 1] = WT;