【问题标题】:munmap_chunk(): invalid pointer Error while making an Array data structure in C++munmap_chunk():在 C++ 中创建数组数据结构时出现无效指针错误
【发布时间】:2021-08-21 06:59:50
【问题描述】:

我尝试解决许多关于 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 可用。

【问题讨论】:

  • 注意:我正在使用命名空间std 并包含iostream
  • 如何获取munmap_chunk(): invalid pointer?模板数组从未在代码中使用。
  • delete[] 并且deletefree 都不能跟随new[]
  • 你应该发帖minimal reproducible example。你应该学过stackoverflow用户指南吧?
  • 告诉我,cap

标签: c++ pointers memory-management


【解决方案1】:

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

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

【讨论】:

  • 如果我发送上限会发生什么
  • 修复了“非法容量:”+std::to_string(cap)
  • 确保在 removeAt 函数中抛出 out_of_range 时执行类似操作。
【解决方案2】:

感谢@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 时更新。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-08
    • 2014-05-14
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 2020-12-10
    相关资源
    最近更新 更多