微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

munmap_chunk(): 在 C++ 中创建数组数据结构时出现无效指针错误

如何解决munmap_chunk(): 在 C++ 中创建数组数据结构时出现无效指针错误

我尝试解决许多关于 munmap_chunk(): invalid pointer 错误的类似问题,但我不知道该怎么做。我也尝试添加 free 命令。

我是 C++ 新手,通常使用 Python 和 Java,所以指针和内存管理的整个概念对我来说都是新的。如果有人能解释我做错了什么,那就太好了。

这是我的 Array 类的通用 T 代码

#include <iostream>
using namespace std;
template <typename T>
class Array {
    private:
        T *arr;
        int len = 0; //length the user thinks the array is
        int capacity = 0; //actual array capacity
    public:
        Array(int cap=16){
            if (cap<0){
                throw invalid_argument("Illegal Capacity: "+cap);
            }
            capacity = cap;
            arr = new T[cap];
            for(int i=0; i<capacity; i++){
                arr[i] = 0;
            }
            
        }
        ~Array(){ delete [] arr; }
        T& operator[](int index){ return arr[index]; }
        
        int size(){ return len; }
        
        bool isEmpty(){ return size() == 0; }

        T get(int index){ return arr[index]; }
        
        void set(int index,T elem){ arr[index] = elem; }
        
        void clear(){
            for(int i = 0; i < capacity; i++)
                arr[i] = 0;
            len = 0;
        }
        void add(T elem){
            if (len+1 > capacity){
                if (capacity == 0) capacity = 1;
                else capacity*=2;
                T *newarr = new T[capacity];
                for (int i = 0; i < len; i++){
                    newarr[i] = arr[i];
                }
                delete [] arr;
                arr = newarr;
            }
            arr[len++]=elem;
        }
        T removeAt(int rmIndex){
            if (rmIndex >= len || rmIndex < 0) throw out_of_range(rmIndex +" out of range for len " + len);
            T data = arr[rmIndex];
            T *newarr = new T[len-1];
            for (int i=0,j=0; i < len; i++,j++){
                if (i==rmIndex){
                    j--;
                }
                else{
                    newarr[j]=arr[i];
                }
            }
            delete [] arr;
            arr = newarr;
            capacity = --len;
            return data;
        }
        bool remove(T t){
            for (int i=0; i<len; i++){
                if (arr[i]==t){
                    removeAt(i);
                    return true;
                }
            }
            return false;
        }
        int indexOf(T t){
            for (int i=0; i<len; i++){
                if (arr[i]==t){
                    return i;
                }
            }
            return -1;
        }
        bool contains(T t){ return indexOf(t) != -1; }
};
int main()
{
    cout << "hello" <<endl;
    Array<float>z(122);
    cout << z.size() << endl;
    for (int i = 0; i < z.size(); i++){
        z.set(i,(float)i);
    }
    for (int i = 0; i < z.size(); i++){
        cout << z.get(i);
    }
    cout << z.size() << endl;
    return 0;
}

输出只有 hello world,没有其他任何东西。

我一直在学习 this video 并且我正在尝试将那里给出的 Java 代码转换为 C++ 以尝试学习该语言,并且我一直在广泛使用 StackOverflow。对于这个问题,我无法找到问题的根源,所以请帮助我。

尝试将其改编为 C++ 的 Java 代码可用 here

解决方法

size() 函数取决于正在设置的 len 成员,而事实并非如此。

您还应该注意表达式 "Illegal Capacity: " + cap 不会将 cap 的值附加到字符串的末尾。它执行指针算术,如果 cap 小于零,您将使用指向内存的指针构造异常before 字符串文字的开头。

,

感谢@S.M. @anastaciu 和 @jkb 提供指导。

这里发布的原始代码是:

#include <iostream>
using namespace std;
template <typename T>
class Array {
 private:
  T *arr;
  int len = 0;
  int capacity = 0;

 public:
  Array(int cap = 16) {
    if (cap < 0) {
      throw invalid_argument("Illegal Capacity: " + cap);
    }
    capacity = cap;
    arr = new T[cap];
    for (int i = 0; i < capacity; i++) {
      arr[i] = 0;
    }
  }
  ~Array() { delete arr; }
  T &operator[](int index) { return arr[index]; }

  int size() { return len; }

  bool isEmpty() { return size() == 0; }

  T get(int index) { return arr[index]; }

  void set(int index,T elem) { arr[index] = elem; }

  void clear() {
    for (int i = 0; i < capacity; i++) arr[i] = 0;
    len = 0;
  }
  void add(T elem) {
    if (len + 1 > capacity) {
      if (capacity == 0)
        capacity = 1;
      else
        capacity *= 2;
      T *newarr = new T[capacity];
      for (int i = 0; i < len; i++) {
        newarr[i] = arr[i];
      }
      free(arr);
      arr = newarr;
    }
    arr[len++] = elem;
  }
  T removeAt(int rmIndex) {
    if (rmIndex >= len || rmIndex < 0)
      throw out_of_range(rmIndex + " out of range for len " + len);
    T data = arr[rmIndex];
    T *newarr = new T[len - 1];
    for (int i = 0,j = 0; i < len; i++,j++) {
      if (i == rmIndex) {
        j--;
      } else {
        newarr[j] = arr[i];
      }
    }
    free(arr);
    arr = newarr;
    capacity = --len;
    return data;
  }
  bool remove(T t) {
    for (int i = 0; i < len; i++) {
      if (arr[i] == t) {
        removeAt(i);
        return true;
      }
    }
    return false;
  }
  int indexOf(T t) {
    for (int i = 0; i < len; i++) {
      if (arr[i] == t) {
        return i;
      }
    }
    return -1;
  }
  bool contains(T t) { return indexOf(t) != -1; }
};
int main() {
  Array<float> z(122);
  for (int i = 0; i < z.size(); i++) {
    z.set(i,(float)i);
    std::cout << z[i];
  }
  return 0;
}

每当使用 new [] 时,它都需要与 delete [] 配对。不应使用 freedelete。这是这里的第一个问题,但这不是导致代码无法工作的原因。

主代码从不初始化 len,因此当使用 size() 函数时,它返回 0,因此从不输入 for loop

每次出现 len 时都需要更新 set

因此,主要问题在于逻辑本身。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。