[英]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.