带有双精度但不带整数的模板的进程返回-1073741819(0xC0000005)

时间:2019-11-18 17:52:40

标签: c++ templates

我试图制作一个动态数组,在数组的开头添加元素。它与int一起正常工作,但是当我尝试加倍时,它给我错误处理返回-1073741819(0xC0000005)。调试它可以正常运行,并且都在范围之内,但是当我运行时它崩溃了。

这是标题:

#define DYNAMICARRAY_H
#include <cstddef>

template <class T>
class DynamicArray
{
    public:
        DynamicArray();
        DynamicArray(size_t);
        DynamicArray(const DynamicArray&);
        virtual ~DynamicArray();

        DynamicArray& operator=(const DynamicArray&);
        T &operator[] (size_t);

        void add(T element);
        size_t getCapacity();
        size_t getLength();
        bool isEmpty();
        void print();
        void resizeArr();

    protected:

    private:
        T *arr;
        size_t capacity;
        size_t length;
};
#endif // DYNAMICARRAY_H

这是.cpp

#include "DynamicArray.h"
#include <iostream>

template <class T>
DynamicArray<T>::DynamicArray()
{
    length = 0;
    capacity = 1;
    arr = (T*)malloc(capacity * sizeof(arr));
    if(!arr){
        throw std::bad_alloc();
    }

}

template <class T>
DynamicArray<T>::DynamicArray(size_t newSize)
{
    length = 0;
    capacity = newSize;
    arr = (T*)malloc(capacity * sizeof(arr));
    if(!arr){
        throw std::bad_alloc();
    }
}

template <class T>
DynamicArray<T>::~DynamicArray()
{
    delete[] arr;
    delete arr;
    delete &capacity;
    delete &length;
}

template <class T>
DynamicArray<T>::DynamicArray(const DynamicArray& other)
{
    length = other.length;
    capacity = other.capacity;
    arr = (T*)malloc(capacity * sizeof(arr));
    if(!arr){
        throw std::bad_alloc();
    }

    for(size_t i = 0; i < length; i++){
        arr[i] = other.arr[i];
    }

}

template <class T>
DynamicArray<T>& DynamicArray<T>::operator=(const DynamicArray& rhs)
{
    if (this == &rhs){
        return *this;
    }

    delete[] arr;

    length = rhs.length;
    capacity = rhs.capacity;
    arr = (T*)malloc(capacity * sizeof(arr));
    if(!arr){
        throw std::bad_alloc();
    }

    for(size_t i = 0; i < length; i++){
        arr[i] = rhs.arr[i];
    }

    return *this;
}

template <class T>
size_t DynamicArray<T>::getLength()
{
    return length;
}

template <class T>
size_t DynamicArray<T>::getCapacity()
{
    return capacity;
}

template <class T>
bool DynamicArray<T>::isEmpty(){
    return length == 0;
}

template <class T>
T &DynamicArray<T>::operator[] (size_t index)
{
    if(index >= length){
        std::cout << "Array index out of bounds" << "\n";
        exit(0);
    }
    return arr[index];
}

template <class T>
void DynamicArray<T>::add(T element)
{
    if(length >= capacity){
        resizeArr();
    }
    if(!isEmpty()){
        for(size_t i = length; i > 0; i--){
            arr[i] = arr[i-1];
        }
    }

    arr[0] = element;
    length ++;

}

template <class T>
void DynamicArray<T>::print()
{
    if(length == 0){
        std::cout << "The array is empty!";
    }
    else{
        for(size_t i = 0; i < length; i++){
            std::cout << arr[i] << " ";
        }
    }
    std::cout << "\n";
}

template <class T>
void DynamicArray<T>::resizeArr(){
    size_t newCapacity = capacity * 2;
    T *arr2 = (T*)realloc(arr, newCapacity * sizeof(arr));

    if(!arr2){
        std::cout << "Bad memory allocation";
        throw std::bad_alloc();
    }

    arr = arr2;
    capacity = newCapacity;
}

template class DynamicArray<double>;
template class DynamicArray<int>;

主要

#include "DynamicArray.h"
#include <cstdlib>
#include <time.h>
#include <cstddef>

using namespace std;

int main()
{
    srand (time(NULL));


    DynamicArray<int> d(5);
    int randomInt;
    for(size_t i = 0; i < d.getCapacity(); i++){
        randomInt = rand()% 100;
        d.add(randomInt);
    }

    d.print();


    d.add(5);
    d.add(55);
    d.add(3);
    d.add(33);
    d.add(37);

    d.print();

    delete &d;

    cout << "\n\n";

    DynamicArray<double> d2(5);

    double randomDouble;

    for(size_t i = 0; i < d2.getCapacity() - 3; i++){
        //randomDouble = (double)rand() / ((double)RAND_MAX);
        randomDouble = 0.5f;
        d2.add(randomDouble);
        d2.print();
    }

    d2.print();

    return 0;
}

它在第二秒就崩溃了,我试图确保所有设置正确,但是仍然无法正常工作

for(size_t i = 0; i < d2.getCapacity() - 3; i++){
        //randomDouble = (double)rand() / ((double)RAND_MAX);
        randomDouble = 0.5f;
        d2.add(randomDouble);
        d2.print();
    }

2 个答案:

答案 0 :(得分:5)

arr = (T*)malloc(capacity * sizeof(arr));

delete[] arr;
delete arr;
delete &capacity;
delete &length;

delete &d;

您传递的指针分别指向delete[]delete未返回的new[]new。该程序的行为是不确定的。相关语言规则:

  

[expr.delete]

     

...在单对象删除表达式中,删除操作数的值可以是空指针值,指向由先前的new表达式创建的非数组对象的指针或指向子对象的指针表示此类对象的基类。如果不是,则行为是不确定的。在数组删除表达式中,删除操作数的值可以是空指针值,也可以是由先前数组new-expression产生的指针值。   如果不是,则行为是不确定的。 ...

程序的每个delete表达式都违反此规则。

要解决此问题,必须在分配给freemallocrealloc的内存上始终使用strdup,并将delete与分配给{ {1}},new,并为delete[]分配了指针,绝对没有取消分配功能的指针指向非动态对象,例如成员变量或具有自动或静态存储持续时间的对象(或无效指针)。

答案 1 :(得分:2)

arr = (T*)malloc(capacity * sizeof(arr));

sizeof(arr)sizeof(T*)相同,我想这不是您想要的。 应该是sizeof(*arr)sizeof(T)


除此之外,不要像其他人已经指出的那样混合使用malloc/deletenew/free

如果您使用C语言,请使用malloc/free,如果您使用C ++,请使用new/delete

使用new会将以上内容更改为

arr = new T[capacity];

完全避免调整整个尺寸。