删除类数组指针时出错

时间:2018-03-09 08:53:27

标签: c++ windows

尝试弄清楚为什么在这个数组指针上使用delete时出现错误?

尝试加载png图片,不确定最新情况

使用delete[] chunks;

时出错

代码

typedef struct {
    char r;
    char g;
    char b;
    char a;
} pixel;

class chunk {
public:
    unsigned char length[4];
    unsigned char type[4];
    unsigned char* data;
    unsigned char CRC[4];

    ~chunk()
    {
        delete[] data;
    }
};

class PNG
{
public:
    PNG();
    PNG(std::string filename);
    ~PNG();
    void loadFile(std::string filename);
    pixel* get();
private:
    pixel * img;
    int width;
    int height;
    int bitdepth;
    int colourtype;
    int compressionmethod;
    int filtermethod;
    int interlacemethod;

    unsigned char* data;
    std::ifstream* file;

    int char2int(unsigned char* arr, int start);
};

void PNG::loadFile(std::string filename)
{
    file = new std::ifstream(filename.c_str(), std::ios::in | std::ios::binary);

    size_t size = 0;
    file->seekg(0, std::ios::end);
    size = file->tellg();
    file->seekg(0, std::ios::beg);

    data = new unsigned char[size];
    file->read((char*)data, size);

    /*
    for (int i = 0; i < size; i++) {
    std::cout << std::hex;
    std::cout.width(2);
    std::cout.fill('0');
    std::cout << (int)data[i] << std::endl;
    }
    */

    size_t index = 8; // ignore header
    chunk* chunks = new chunk[size];

    size_t chunkindex = 0;
    while (index < size) {
        for (int i = 0; i < 4; i++) {
            chunks[chunkindex].length[i] = data[index++];
        }
        std::cout << "Size of Chunk " << chunkindex + 1 << ": " << char2int(chunks[chunkindex].length, 0) << std::endl;
        chunks[chunkindex].data = new unsigned char[char2int(chunks[chunkindex].length, 0)];

        for (int i = 0; i < 4; i++) {
            chunks[chunkindex].type[i] = data[index++];
        }

        if (char2int(chunks[chunkindex].length, 0) != 0) {
            for (int i = 0; i < char2int(chunks[chunkindex].length, 0); i++) {
                chunks[chunkindex].data[i] = data[index++];
            }
        }

        for (int i = 0; i < 4; i++) {
            chunks[chunkindex].CRC[i] = data[index++];
        }

        chunkindex++;
    }

    for (int i = 0; i < chunkindex; i++) {
        char name[5];
        for (int j = 0; j < 4; j++) {
            name[j] = chunks[i].type[j];
        }
        name[4] = '\0';

        if (strcmp(name, "IHDR") == 0) {
            std::cout << "FOUND IHDR" << std::endl;
            width = char2int(chunks[i].data, 0);
            height = char2int(chunks[i].data, 4);
            bitdepth = chunks[i].data[8];
            colourtype = chunks[i].data[9];
            compressionmethod = chunks[i].data[10];
            filtermethod = chunks[i].data[11];
            interlacemethod = chunks[i].data[12];

        }
        else if (strcmp(name, "PLTE") == 0) {
            std::cout << "FOUND PLTE" << std::endl;
        }
        else if (strcmp(name, "IDAT") == 0) {
            std::cout << "FOUND IDAT" << std::endl;
        }
        else if (strcmp(name, "IEND") == 0) {
            std::cout << "FOUND IEND" << std::endl;
        }

    }


    std::cout << "Width: " << width << std::endl;
    std::cout << "Height: " << height << std::endl;

    delete[] chunks;
}

错误: 0xC0000005:访问冲突读取位置0xFFFFFFFFFFFFFFFF

2 个答案:

答案 0 :(得分:5)

将默认构造函数添加到chunk类。

chunk::chunk () {
   data = 0;
}

致电时

    chunk* chunks = new chunk[size];
创建了

size个对象,并且所有创建的对象都有data变量中的垃圾数据 - 此成员未初始化。当你打电话

    delete[] chunks;

对于chunks数组dtor的每个对象都被调用,但是当data成员未设置时,delete[] data是未定义的行为。

data成员未设置chunks数组中的所有对象 - 请参阅while循环:为此行中的data成员分配内存

        chunks[chunkindex].data = new unsigned char[char2int(chunks[chunkindex].length, 0)];

但不适用于所有已创建的对象,因为在每次迭代的while循环中,index会多次增加chunkindex,但index < size只增加一次。当while循环被此chunkIndex停止时,size不等于data,这意味着存在具有单元化for (UIView *object in _mapView.subviews) { if([[[object class] description] isEqualToString:@"GMSUISettingsPaddingView"] ) { for (UIView *settingView in object.subviews) { if([[[settingView class] description] isEqualToString:@"GMSUISettingsView"] ) { for(UIView *view in settingView.subviews) { if([[[view class] description] isEqualToString:@"GMSx_QTMButton"] ) { CGRect frame = view.frame; frame.origin.y -= 60; view.frame = frame; } } } }; } } 成员的块对象。

答案 1 :(得分:0)

您不需要在代码中使用所有这些指针。对于该应用程序,在我看来,您应该求助std::vector来帮助您进行内存管理。并且,有内存泄漏 - 您正在分配std::ifstream对象,而您没有使用匹配的delete发布它。好吧,也许你是在PNG的析构函数中进行的,我们没有看到,但无论如何你还没有关闭你打开的文件。您应该将资源(在本例中为已打开的文件)释放回系统。

对于您粘贴的代码摘录,也许您应该有类似于下面的内容,方法是将裸指针更改为std::vector并将file成员更改为对象而不是指针:

#include <fstream>
#include <iostream>
#include <string>
#include <vector>

typedef struct {
  char r;
  char g;
  char b;
  char a;
} pixel;

class chunk {
public:
  unsigned char length[4];
  unsigned char type[4];
  // unsigned char *data;
  /* let std::vector take care of memory issues */
  std::vector<unsigned char> data;
  unsigned char CRC[4];

  // ~chunk() { delete[] data; }
};

class PNG {
public:
  PNG();
  PNG(std::string filename);
  ~PNG();
  void loadFile(std::string filename);
  pixel *get();

private:
  // pixel *img;
  /* std::vector to the help */
  std::vector<pixel> img;
  int width;
  int height;
  int bitdepth;
  int colourtype;
  int compressionmethod;
  int filtermethod;
  int interlacemethod;

  /* please ! */
  // unsigned char *data;
  std::vector<unsigned char> data;
  // std::ifstream *file;
  /* you don't need a pointer here */
  std::ifstream file;

  int char2int(unsigned char *arr, int start);
};

void PNG::loadFile(std::string filename) {
  file = std::ifstream(filename, std::ios::in | std::ios::binary);

  /* better to check whether file is opened properly */
  // if (file) { ... }
  size_t size = 0;
  file.seekg(0, std::ios::end);
  size = file.tellg();
  file.seekg(0, std::ios::beg);

  data = std::vector<unsigned char>(size);
  file.read(reinterpret_cast<char *>(&data[0]), size);

  /* apparently you are done with the file */
  file.close();

  /*
  for (int i = 0; i < size; i++) {
  std::cout << std::hex;
  std::cout.width(2);
  std::cout.fill('0');
  std::cout << (int)data[i] << std::endl;
  }
  */

  size_t index = 8; // ignore header
  std::vector<chunk> chunks(size);

  size_t chunkindex = 0;
  while (index < size) {
    for (int i = 0; i < 4; i++) {
      chunks[chunkindex].length[i] = data[index++];
    }
    std::cout << "Size of Chunk " << chunkindex + 1 << ": "
              << char2int(chunks[chunkindex].length, 0) << std::endl;
    chunks[chunkindex].data =
        std::vector<unsigned char>(char2int(chunks[chunkindex].length, 0));

    for (int i = 0; i < 4; i++) {
      chunks[chunkindex].type[i] = data[index++];
    }

    if (char2int(chunks[chunkindex].length, 0) != 0) {
      for (int i = 0; i < char2int(chunks[chunkindex].length, 0); i++) {
        chunks[chunkindex].data[i] = data[index++];
      }
    }

    for (int i = 0; i < 4; i++) {
      chunks[chunkindex].CRC[i] = data[index++];
    }

    chunkindex++;
  }

  for (int i = 0; i < chunkindex; i++) {
    char name[5];
    for (int j = 0; j < 4; j++) {
      name[j] = chunks[i].type[j];
    }
    name[4] = '\0';

    if (strcmp(name, "IHDR") == 0) {
      std::cout << "FOUND IHDR" << std::endl;
      width = char2int(&(chunks[i].data[0]), 0);
      height = char2int(&(chunks[i].data[0]), 4);
      bitdepth = chunks[i].data[8];
      colourtype = chunks[i].data[9];
      compressionmethod = chunks[i].data[10];
      filtermethod = chunks[i].data[11];
      interlacemethod = chunks[i].data[12];

    } else if (strcmp(name, "PLTE") == 0) {
      std::cout << "FOUND PLTE" << std::endl;
    } else if (strcmp(name, "IDAT") == 0) {
      std::cout << "FOUND IDAT" << std::endl;
    } else if (strcmp(name, "IEND") == 0) {
      std::cout << "FOUND IEND" << std::endl;
    }
  }

  std::cout << "Width: " << width << std::endl;
  std::cout << "Height: " << height << std::endl;

  // delete[] chunks;
}