Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7761111
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T14:03:43+00:00 2026-06-01T14:03:43+00:00

The class corresponding to this crash is: #ifndef IMAGE_DATA_ #define IMAGE_DATA_ #include <stdexcept> template

  • 0

The class corresponding to this crash is:

#ifndef IMAGE_DATA_
#define IMAGE_DATA_

 #include <stdexcept>

template <typename data_type>
class ImageData 
{
public:
  ImageData(unsigned long width, unsigned long height);
  ~ImageData();
  data_type **&get_data();
  unsigned long int get_width() const
  {
    return _m_Width;
  }
  unsigned long int get_height() const
  {
    return _m_Height;
  }
protected:
  ImageData(ImageData &copy);
  ImageData& operator= (ImageData &copy);
private:
  data_type **_m_rData;
  unsigned long _m_Width;
  unsigned long _m_Height;
};

template <typename data_type>
ImageData<data_type>::ImageData(unsigned long width, unsigned long height) :
  _m_rData(NULL),
  _m_Width(width),
  _m_Height(height)
{
  if (width == 0 || height == 0)
    throw std::runtime_error("Invalid width or height");

  try {
    _m_rData = new data_type*[_m_Height]();
    for (unsigned long int i = 0; i < _m_Height; ++i) {
      _m_rData[i] = NULL;
    }
    for (unsigned long int i = 0; i < _m_Height; ++i) {
      _m_rData[i] = new data_type[_m_Width];
    }
  }
  catch (std::bad_alloc e) {
    throw std::runtime_error("Failure to create space for Image");
  }
}

template <typename data_type>
ImageData<data_type>::~ImageData()
{
  for (unsigned long i = 0; i < _m_Height; ++i) {
      delete [] _m_rData[i];
     _m_rData[i] = NULL;
  }
  delete [] _m_rData;
  _m_rData = NULL;
}

template <typename data_type>
data_type **&ImageData<data_type>::get_data()
{
  return _m_rData;
}

#endif

And it is used in the following manner:

PNGFileReader::PNGFileReader(const std::string &path) :
  _m_Image(NULL),
  _m_pPNG(NULL),
  _m_pPNGInfo(NULL)
{
   ...
  /*
   * Read Image in all at once into users data
   */  
  _m_Image = new ImageData<unsigned char>(width, height);
  png_read_image(_m_pPNG, _m_Image->get_data());
  png_read_end(_m_pPNG, NULL);
  fclose(_m_CFilePointer);
  _m_CFilePointer = NULL;
}

PNGFileReader::~PNGFileReader()
{
  if (_m_CFilePointer) {
    fclose(_m_CFilePointer);
  }
  png_destroy_read_struct(&_m_pPNG, &_m_pPNGInfo, NULL);
  delete _m_Image;
}

When stepping through with the debugger the _m_rData in the ImageData class is the same pointer as when I used new on it. I have even tried to wrap the delete statement inside ImageData destructor with if == NULL statments. However, I still get a sigabrt while running my code. The stack trace from gdb is:

0   __GI_raise  raise.c 64  0x3512a36285    
1   __GI_abort  abort.c 91  0x3512a37b9b    
2   __libc_message  libc_fatal.c    198 0x3512a77a7e    
3   malloc_printerr malloc.c    5021    0x3512a7dda6    
4   _int_free   malloc.c    3942    0x3512a7f08e    
5   ImageData<unsigned char>::~ImageData    imagedata.h 57  0x40236d    
6   PNGFileReader::~PNGFileReader   pngfilereader.cpp   59  0x401ed3    
7   main    main.cpp    8   0x40246a    

UPDATE

For anyone that is curios the following now works. Apparently it is an issue with how png_alligns its data. This forces you I guess to use libpng’s method calls which internally use free and malloc, not new. This is essentially the same things as calling free(data) where data was created with data = new type[N]. The code below depicts how to correctly use libpng.

#ifndef PNG_FILE_READER_H_
#define PNG_FILE_READER_H_

#include "imagedata.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <png.h>
#include <iostream>
#include <vector>
#include <string>

template <typename data_type>
class ImageData;

class PNGFileReader
{
  public:
    // Ctor and Dtor
    PNGFileReader(const std::string &path);
    ~PNGFileReader();

    // For testing purposes
    friend std::ostream &operator<< (std::ostream &out, 
      PNGFileReader *object)
    {
      for (unsigned long i = 0; i < object->get_image_height(); ++i) {
        for (unsigned long j = 0; j < object->get_image_width(); ++j) {
          png_byte c = object->_m_ImageData[i][j];
          out << c;
        }   
      }
      return out;
    }

    // Getters
    long unsigned int get_image_width() const;
    long unsigned int get_image_height() const;

  private:
    // Helper functions:
    bool _create_png_structs();

    // Member variables:
    FILE *_m_CFilePointer;
    unsigned long int _m_ImageWidth;
    unsigned long int _m_ImageHeight;
    png_bytepp _m_ImageData;
    png_structp _m_pPNG;
    png_infop _m_pPNGInfo;

    // Enums
    enum PNGBOOL {NOT_PNG, PNG};
    enum PNGERRORS {ERROR, SUCCESS};
};

#endif /* PNG_FILE_READER_H_ */

#include "pngfilereader.h"
#include "filereader.h"
#include <stdexcept>


PNGFileReader::PNGFileReader(const std::string &path) :
  _m_ImageData(NULL),
  _m_pPNG(NULL),
  _m_pPNGInfo(NULL)
{
  /*
   * Check if first 8 bytes are the correct PNG header
   */ 
  enum {BYTES_TO_READ = 8};
  unsigned char sig[BYTES_TO_READ];
  FileReader(path, sig, BYTES_TO_READ);
  bool not_png = png_sig_cmp(sig, 0, BYTES_TO_READ);
  if (not_png) {
    throw std::runtime_error("Your file is not of PNG format");
  }

  /*
   * Create the png structs using a FILE *. libpng requires
   * this type and will not take a C++ stream
   */ 
  _m_CFilePointer = fopen(path.c_str(), "rb");
  if (!_m_CFilePointer) {
    throw std::runtime_error("Failure to open PNG file");
  }
  if (!_create_png_structs()) {
    throw std::runtime_error("Failure to create PNG structs");   
  }

  /*
   * Initialize PNG io and read data into PNG structs
   */ 
  png_init_io(_m_pPNG, _m_CFilePointer);
  png_read_info(_m_pPNG, _m_pPNGInfo);
  _m_ImageHeight = png_get_image_height(_m_pPNG, _m_pPNGInfo);
  _m_ImageWidth = png_get_rowbytes(_m_pPNG, _m_pPNGInfo);

  /*
   * Create sufficient PNG Space and Read Image in all at
   * once into users data. Note that you have to use png's
   * types to prevent sigabrt (6) while freeing memory.
   */
  _m_ImageData = (png_bytepp)png_malloc(_m_pPNG,
    sizeof(png_bytep)*_m_ImageHeight);
  if (_m_ImageData == NULL) {
    throw std::runtime_error("Memory allocation failure");
  }
  for (unsigned long int i = 0; i < _m_ImageHeight; ++i) {
     _m_ImageData[i] = NULL;
  }
  for (unsigned long int i = 0; i < _m_ImageHeight; ++i) {
    _m_ImageData[i] = (png_bytep)png_malloc(_m_pPNG,
      sizeof(png_byte)*_m_ImageWidth);
    if (_m_ImageData[i] == NULL) {
      throw std::runtime_error("Memory allocation failure.");
    }
  }
  png_read_image(_m_pPNG, _m_ImageData);
  png_read_end(_m_pPNG, NULL);
  fclose(_m_CFilePointer);
  _m_CFilePointer = NULL;
}

PNGFileReader::~PNGFileReader()
{
  if (_m_CFilePointer) {
    fclose(_m_CFilePointer);
  }
  /*
   * Free all resources (-1)
   */
  png_free_data(_m_pPNG, _m_pPNGInfo, PNG_FREE_ALL, -1);
  for (unsigned long int i = 0; i < _m_ImageHeight; ++i) {
    png_free(_m_pPNG, _m_ImageData[i]);
  }
  free(_m_ImageData);
  png_destroy_read_struct(&_m_pPNG, &_m_pPNGInfo, NULL);
}
// Getters
long unsigned int PNGFileReader::get_image_width() const
{
  return _m_ImageWidth;
}

long unsigned int PNGFileReader::get_image_height() const
{
  return _m_ImageHeight;
}

// Private helper functions
bool PNGFileReader::_create_png_structs()
{
  /* 
   * Create the pointer to main libpng struct, as well as
   * two info structs to maintain information after, and
   * prior to all operations on png m_Data. Only necessary
   * to release resource after function succeeds.
   */
  _m_pPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
    NULL, NULL);
  if (!_m_pPNG){
    return PNGFileReader::ERROR;
  }

  _m_pPNGInfo = png_create_info_struct(_m_pPNG);
  if (!_m_pPNGInfo) {
    return PNGFileReader::ERROR;
  }

  return PNGFileReader::SUCCESS;
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T14:03:44+00:00Added an answer on June 1, 2026 at 2:03 pm

    If you need a really 2D array to pass to a library, but want to have the flexibility of a jagged array, what you do is

    1. Allocate the first level pointer block as usual
    2. Instead of allocating m separate rows of n cells (one for each pointer in the first level block) you allocate a single set of n*m cells and then set the first level pointers to point at every nth location. This way the main allocation is sized and laid out in memory just as a 2D array, but you can still use the two-pointer-dereference [][] syntax to get to the cells.
    3. Pass the start of the second level allocation to the library.

    This works because there are strict requirements on who multidimensional arrays are laid out in memory (i.e. the must be contiguous at every level of interpretation).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

class foo { public: void say_type_name() { std::cout << typeid(this).name() << std::endl; } };
Suppose I have an Orders table in my database and a corresponding model class
class test <T> where T : class { public void Write<T>() { Console.Write(typeof(T).FullName); }
class Widget { public: Widget() { cout<<~Widget()<<endl; } ~Widget() { cout<<~Widget()<<endl; } void* operator
class Foo(){ public List<string> SomeCollection; } I need to implement an event which can
I want to find a class corresponding to another class within the same div
I have a database table and a corresponding entity class (POCO with change tracking
I have a class TreeNode: public abstract class TreeNode<T>{ . . . public Collection<TreeNode<T>>
I am trying to create a UML class diagram and corresponding class definition (in,
I'm trying to convert a string to its corresponding class (i.e. true to true

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.