首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >模板中的错误std::bad_array_new_length

模板中的错误std::bad_array_new_length
EN

Stack Overflow用户
提问于 2021-07-05 09:16:25
回答 1查看 804关注 0票数 4

我试图定义自己的类模板Array<T>来实践模板的使用。

我生成的代码构建正确,但在执行时会出现以下错误

代码语言:javascript
运行
复制
terminate called after throwing an instance of 'std::bad_array_new_length'
  what():  std::bad_array_new_length

我想我已经找到了解决这个问题的方法,但是我想看看前面的代码中是否有潜在的错误,如果是的话,是哪一个。

这是我以前写过的代码:

代码语言:javascript
运行
复制
#include <iostream>

class Empty{
private:
    char error;
public:
    Empty(char e) : error(e) { std::cout << "Azione non disponibile, lista vuota" << std::endl;}
};

template <class T>
class Array;

template <class T>
std::ostream& operator<<(std::ostream&,const Array<T>&);

template <class T>
class Array{
    friend std::ostream& operator<< <T> (std::ostream&,const Array<T>&);
private:
    T* arr;
    unsigned int size;
    unsigned int capacity;

    static T* copia(T* a, unsigned int s, unsigned int c){
        if(c > 0) {
            T* app = new T[c];
            for (int i = 0; i<s; ++i) {
                app[i] = a[i];
            }
            return app;
        }else return nullptr;
    }

public:
    Array(int k = 0, const T& t = T()) : size(k > 0 ? k : 0), capacity(size), arr(k > 0 ? new T[size] : nullptr){
        for (int i = 0; i < k ; ++i) arr[i] = t;
    }

    Array(const Array& a) : size(a.size), capacity(a.capacity), arr(copia(a.arr,a.size,a.capacity)){}

    Array& operator=(const Array& a){
        if(this != &a){
            delete[] arr;
            capacity = size = a.size;
            arr = copia(a.arr,a.size,a.capacity);
        }
        return *this;
    }

    ~Array(){delete[] arr;}

    void pushBack(const T& t) {
        if(size == capacity){
            capacity > 0 ? capacity *= 2 : capacity = 1;
            T* app = copia(arr,size, capacity);
            delete[] arr;
            arr = app;
        }
        ++size;
        arr[size-1] = t;
    }

    T popBack() {
        if (size != 0) {
            T temp = arr[size - 1];
            --size;
            return temp;
        } else throw Empty('e');
    }

};

template <class T>
std::ostream& operator<<(std::ostream& os ,const Array<T>& a){
    for (int i = 0; i < a.size; ++i) {
        os << a.arr[i] << ' ';
    }
    std::cout << std::endl;
    return os;
}

int main(){

    Array<int> a(5,5),e;
    std::cout << a << std::endl;

    a.pushBack(16);
    a.pushBack(17);
    a.pushBack(18);

    std::cout << a << std::endl;

    return 0;
}

如果我在没有a.pushBack(x)函数调用的情况下运行这段代码,它就能工作。

只要插入一个函数调用,输出中就会出现错误。

在调试过程中,我意识到我编写T* arr的行不是正确的。

知道构造函数遵循自己的子对象的初始化顺序,要构造的第一个元素是指针。由于我试图用维度T创建元素向量,因此正确地给出了错误,因为我还没有初始化整数大小。

所以我通过交换线路解决了这个问题。

代码语言:javascript
运行
复制
template <class T>
class Array{
    friend std::ostream& operator<< <T> (std::ostream&,const Array<T>&);
private:
    unsigned int size;
    unsigned int capacity;
    T* arr;
    ...
};

但在这一点上,我想知道:为什么,如果我不进行函数调用,我就不会得到相同的错误,知道在构造时的大小是未知的?

从逻辑上讲,在这种情况下,问题也应该发生,但一切似乎都正常。

PS:不要指望我没有处理抛出的异常,代码还没有完全完成,但就目前而言,我希望至少实现三条规则。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-05 20:03:00

在jdoodle.com中用GCC 9.1.0编译,我始终得到一个bad_alloc运行时异常与您的原始代码。

我添加了一个具有不同签名的新构造函数,这样我就可以看到它用于分配数组注释的size值:即使存在这个新的ctor,也防止了bad_alloc错误的发生,不管它是否被调用。

代码语言:javascript
运行
复制
Array(char c, int k = 0, const T& t = T()) : 
    size(k > 0 ? k : 0), 
    capacity(size), 
    arr(DebugInit(size)){
    for (int i = 0; i < k ; ++i) arr[i] = t;
}

T* DebugInit( unsigned long size_init )
{
    std::cout << "DebugInit size_init=" << size_init << " cap=" << capacity << std::endl;
    return size_init > 0 ? new T[size_init] : nullptr;
}

当使用这种新的ctor时,结果似乎是随机的。size_init每次变化,这与使用尚未初始化的成员字段一致。

在原始代码中,可能是size碰巧始终有0。通过添加更多的代码,即使从未调用过,编译后的版本也会访问size的随机但现在非零的值。

这似乎是典型的“未定义的行为”。如果您在初始化size之前使用它,则无法保证它将包含什么内容。如果幸运的话,size在初始化之前将始终返回0,并且会得到一个分配错误。但是,对代码的小改动可能会开始返回size的随机值。如果未初始化的size的值比您想要的要大得多,那么您直到以后才会发现问题,或者永远不会。

在更多地使用代码之后,std::bad_alloc异常又回来了!所以,绝对不能保证!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68253560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档