簡體   English   中英

分段錯誤:C++ IntVector 中的 11

[英]Segmentation fault: 11 in C++ IntVector

我正在嘗試在 C++ 中實現一個 intvector,並收到“分段錯誤:11”錯誤。 我知道這與 memory 管理有關,考慮到我對 C++ 有多新,這絕對是一個很小的錯誤。 我用 valgrind 調試了代碼,得到了如下消息:

使用大小為 8 的未初始化值、大小為 4 的無效讀取、條件跳轉或移動取決於未初始化的值。

我最好的猜測是它與我如何實現 arrays 有關。 我最初將 arrays 存儲在堆上,但將其更改為堆棧,仍然出現相同的錯誤。 我已經在 java 中實現了一個 intvector,所以我在這里嘗試使用類似的邏輯,這可能是問題的一部分。

#include <iostream>
#include "IntVector.h" 
#include <cmath>
using namespace std;

int num_elements = 0;
int array_size = 0;
int expansion_factor;

void IntVector::expandArray(){

   int tempArr[array_size*2];

  for(int i =0;i<array_size;i++){
    tempArr[i] = array[i]; 
  }

  array = tempArr;
  array_size = array_size * 2;

}
void IntVector::add(int val){

  int tempArr[array_size];

   if(array_size == num_elements){

     expandArray();
     array[num_elements] = val;    
   }
   else{
     for(int i = 0;i<array_size;i++){
       tempArr[i] = array[i];
     }
     tempArr[num_elements] = val;
     array = tempArr;
   }
   num_elements++;
}
void IntVector::remove(int index){   
  }
int IntVector::get(int index) const{
    return index;
  }
void IntVector::removeLast(){
  }
void IntVector::set(int index, int val){
  }

std::string IntVector::toString()const {
    return "";
  }

IntVector::IntVector(int initial_size){
  int* array = new int[initial_size];

  }

IntVector:: ~IntVector(){
  delete[] array;
}


int main(){

  IntVector v(0);
  v.add(5);
}
#ifndef INTVECTOR_H_
#define INTVECTOR_H_

using std::cout;
class IntVector {
private:
  int* array;
  int num_elements;
  int array_size;
  int expansion_factor;
  void expandArray();
 public:
  void add(int val);
  void remove(int index);
  int get(int index) const;
  void removeLast();
  void set(int index, int val);
  std::string toString() const;
  IntVector(int initial_size);
  ~IntVector();


};
#endif  

正如評論中提到的,您對 C++ 的理解肯定存在一些漏洞。 實際上,在處理 header 文件時,您應該有一個 main.cpp、someotherfile.h、someotherfile.cpp。 這只是避免重新定義錯誤的最佳實踐。

您訪問私有變量的方式有很多錯誤。 如果 class 有一個私有(甚至公共)變量,您不必在每次想要更改其值時重新聲明它。

擴展向量的方式存在一兩個主要缺陷。 如果向量大小初始化為 0,則 0*2 仍然為 0,因此您實際上從未增加大小。 其次,當您將原始數組 = 設置為新數組時,新數組只是一個本地數組。 這意味着 memory 實際上並沒有被永久分配,一旦 function 結束, temparr 就被銷毀了。

我知道這可能很多,但如果您有任何問題,請隨時提出。

主文件

#include "IntVector.h"

int main()
{
    IntVector v;
    IntVector x(10);

    v.push(5);
    v.push(5);
    v.push(5);
    v.push(5);
    v.push(5);
    v.print();
    cout << endl;

    x.push(5);
    x.push(5);
    x.push(5);
    x.push(5);
    x.push(5);
    x.print();

    return 0;
}

整數向量.h

#include <string>
#include <iostream>
using namespace std;

class IntVector {
private:
    int *array;
    int num_elements;
    int array_size;
    //int expansion_factor =;  you would only need this if you plan on more than double the vector size 
    void expandArray();     //normally c++ array double in size each time they expand

public:
    //Constructors
    IntVector(); //this is a contructor for if nothing is called
    IntVector(int initial_size);

    //setters
    void push(int val);     //add   
    void pop();             //removelast
    void remove(int index); //remove
    void at(int index, int val);    //set

    //Getters
    int at(int index);
    //std::string toString(); I'm changing this to print
    void print();   //will print the contents to the terminal

    //Deconstructor
    ~IntVector();
};

整數向量.cpp

#include "IntVector.h"

//constructors
IntVector::IntVector() //no arguments given
{
    array = new int[0];
    num_elements = 0;
    array_size = 0;
}

IntVector::IntVector(int initial_size)
{
    array = new int[initial_size];
    num_elements = 0;
    array_size = initial_size;
}

void IntVector::expandArray()
{
    int *tempArr;
    if(array_size == 0){
        array_size = 1;
        tempArr = new int[1];
    } else {
        //make sure to allocate new memory
        //you were creating a local array which was destroy after the function was completed
        //using new will allow the array to exist outside the function
        tempArr = new int[array_size * 2];
    }



    for (int i = 0; i < array_size; i++)
    {
        tempArr[i] = array[i];
    }

    //make sure to delete the old array otherwise there is a memory leak.
    //c++ doesn't have a garbage collector
    delete[] array; 


    array = tempArr;
    array_size = array_size * 2;
}
void IntVector::push(int val)
{
    num_elements++;

    //checking if vector needs to increase
    if (array_size <= num_elements)
    {
        expandArray();
        array[num_elements-1] = val;
    }
    else
    {
        array[num_elements-1] = val;
    }

}
void IntVector::remove(int index)
{
    //not sure how to implment this becuase each element has to be a number.
}

int IntVector::at(int index)
{
    return array[index];
}

void IntVector::pop()
{
    num_elements = num_elements-1; //not really removing it from the "vector" but it won't print out again
}
void IntVector::at(int index, int val)
{
    array[index] = val;
}

void IntVector::print()
{
    for (int i = 0 ; i < num_elements; i++)
    {
        cout << array[i] << " ";
    }
    cout << endl;
}



IntVector::~IntVector()
{
    delete[] array;
}

output

5 5 5 5 5

5 5 5 5 5

希望評論有所幫助。 我更改了函數的名稱以更好地匹配 C++ 中已經存在的實際向量 class。 我認為將這樣的已定義函數分開是很好的,因為您可以更好地了解它們的實際工作方式,而不僅僅是如何使用它們。

如果您有任何問題,請發表評論

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM