我的ArrayList类重新分配中存在分段错误

时间:2018-07-06 02:10:13

标签: c++ segmentation-fault realloc

出于学习目的,我试图创建一个基本的ArrayList类,该类可以添加元素并在需要时调整自身大小。目前,我设法创建了一个构造函数并重载了数组访问运算符,并添加了一个append函数以将元素添加到数组的后面。但是,一旦触发realloc,程序就会因Segmentation Fault: 11而崩溃。但是,奇怪的是,如果我更改代码,则第一次执行该代码时就不会出现分段错误。仅当重新运行该可执行文件时,它才会失败,因此我怀疑free()的调用无法正常工作。直到重新分配为止的所有元素都似乎已成功添加。

我在.cpp文件中定义了我的班级,因为模板定义无法拆分为标头和其他文件。

structures.cpp

#include <cstdlib>
#include <stdexcept>

template<typename T> class ArrayList {
    private:
        T* pointer;
        unsigned short space;
    public:
        ArrayList();
        ~ArrayList();
        T& operator[](unsigned short index);
        const T& operator[](unsigned short index) const; 
        unsigned short length;
        void append(T element);
};

template<typename T> ArrayList<T>::ArrayList() {
    length = 0;
    space = 10;
    pointer = (T*)malloc(space*sizeof(T));
}

template<typename T> ArrayList<T>::~ArrayList() {
    free(pointer);
}

template<typename T> T& ArrayList<T>::operator[](unsigned short index) {
    if (index > length) throw std::out_of_range("Index out of bounds.");
    return *(pointer + sizeof(T)*index);
}

template<typename T> void ArrayList<T>::append(T element) {
    if (length == space) {
        space *= 2;
        pointer = (T*)realloc(pointer, sizeof(T)*space);
    }
    *(pointer + sizeof(T)*length) = element;
    ++length;
}

main.cpp

#include <iostream>
#include "structures.cpp"

int main(int argc, char** argv) {
    ArrayList<unsigned> arr;
    int l = 11;
    for (int i = 0; i < l; ++i) {
        std::cout << "Current index: " << i << std::endl;
        arr.append(i);
    }
    std::cout << "Finished writing to array" << std::endl;
    for (int i = 0; i < l; ++i) {
        std::cout << "Index: " << i << " Value: " << arr[i] << std::endl;
    }
    return 0;
}

输出:

Current index: 0
Current index: 1
Current index: 2
Current index: 3
Current index: 4
Current index: 5
Current index: 6
Current index: 7
Current index: 8
Current index: 9
Current index: 10
Segmentation fault: 11

1 个答案:

答案 0 :(得分:0)

问题出在这里(在您的append函数中):

*(pointer + sizeof(T)*length) = element;

您会忘记pointer是指向T元素数组(而不是字节数组)的指针(指向第一个元素)。您正在做的(完全)等于

pointer[sizeof(T)*length] = element;

这显然是错误的,很容易越界并导致undefined behavior

正确的方法很简单

pointer[length] = element;

或者如果您被迫使用显式指针算法(我没有其他原因)

*(pointer + length) = element;