Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Multi-Dimensional arrays in Class
Index -> Programming, C++ -> C++ Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
copthesaint




PostPosted: Thu Oct 18, 2012 11:07 am   Post subject: Multi-Dimensional arrays in Class

I am having difficulty making a two dimensional array in my class. This is the output to my consol screen when the program runs:

EDIT: sorry but I cant put this character in code Tag
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//it repeats for the width set

These are the errors I get:

code:
First-chance exception at 0x536057aa (msvcr100d.dll) in CharacterBuffer.exe: 0xC0000005: Access violation reading location 0xfdfdfdf1.
Unhandled exception at 0x77bd15de in CharacterBuffer.exe: 0xC0000005: Access violation reading location 0xfdfdfdf1.
The program '[3012] CharacterBuffer.exe: Native' has exited with code -1073741819 (0xc0000005).


And here is my Source code:

c++:
//Buffer.h
#include <iostream>
using namespace std;

class Buffer {

public:

        Buffer (); // new no size empty
        Buffer (int = 0,int = 0); // new empty
        Buffer (int = 0,int = 0, char = ' '); // new
        Buffer (Buffer &); // copy?
        ~Buffer (); // delete buffer

        void flood (char); // set all in size

        void setPoint (int, int, char); // set point

        char getPoint (int,int)const; // get point at character

        void drawBuffer (); // Draws to output
        void drawBuffer (Buffer&); // draw to another buffer
        void drawBuffer (Buffer& , int, int); // draw to another buffer at pos y,x
        void drawBuffer (Buffer&, char); // draw to another buffer with checking white space character
        void drawBuffer (Buffer&, char,int,int); //draw to another buffer at pos y,x and wwhite space character 

protected:
       
        char **bArr;
        int wSize;
        int hSize;

};

/*Creates a new empty buffer*/
Buffer::Buffer() {
        bArr = NULL;
}

/*Creates a new buffer and resizes the multi dimensional array leaving it empty*/
Buffer::Buffer(int arrHeight, int arrWidth)  { 
        if(arrWidth <= 0 || arrHeight <= 0)
    {
        throw "Buffer cannot have neutral or negative values.";
    }
        bArr = new char*[arrHeight] ;
        for(int i=0; i<arrHeight; ++i) {
                bArr[i] = new char[arrWidth] ;
                bArr[i][arrWidth-1] = NULL ;
        }
        hSize = arrHeight;
        wSize = arrWidth;
}

/*Creates a new buffer and resizes the multi dimensional array
initializing it to a character*/

Buffer::Buffer(int arrHeight, int arrWidth, char floodChar)  {
        if(arrWidth <= 0 || arrHeight <= 0)
    {
        throw "Buffer cannot have neutral or negative values.";
    }
        bArr = new char*[arrHeight] ;
        for(int i=0; i<arrHeight; ++i) {
                bArr[i] = new char[arrWidth];
                for (int j = 0; j <arrWidth; j++){
                        bArr[i][j] = floodChar;
                }
        }
        hSize = arrHeight;
        wSize = arrWidth;
}
/*Creates a new buffer using the data from an old buffer*/
Buffer::Buffer(Buffer &objBuffer) {
        char **b=NULL;
        int i=0,j=0,iColumn;
        b=objBuffer.bArr ;
        while(*(b+i)) {
                ++i;
        }
        bArr = new char*[i] ;
        iColumn = strlen(objBuffer.bArr[0]) ;
        for(j=0; j<i; ++j) {
                bArr[j] = new char[iColumn+1] ;
                bArr[j][iColumn-1] = NULL ;
        }
        i=0;
        b=objBuffer.bArr ;
        while(*(b+i)) {
                strcpy(*(bArr+i),*(b+i));
                ++i;
        }
        hSize = i;
        wSize = j;
}
/*Deletes buffer, remove dynamically alocated memory*/
Buffer::~Buffer() {
        int i=0;
        while(bArr[i]) {
                if(bArr[i]) {
                        delete bArr[i] ;
                }
                ++i;
        }
        if(bArr){
                delete []bArr ;
        }
}

void Buffer::drawBuffer (){
        int i=0, j=0;
        while (i < hSize){
                while (j < wSize){
                        cout << bArr [i][j];
                        j++;
                }
                i++;
        }       
}


c++:
//main.cpp
#include <iostream>
#include <cstdlib>
#include "Buffer.h"
        using namespace std;

int main (int argc, char * argv []){
        Buffer splash = Buffer (48,80,char (178));
        splash.drawBuffer();

        splash.~Buffer();
        return 0;
}


Im just trying to learn how too, Because I would like to learn something while the rest of my class are working on random. Thanks if you spot anything.
Sponsor
Sponsor
Sponsor
sponsor
copthesaint




PostPosted: Thu Oct 18, 2012 3:27 pm   Post subject: Re: Multi-Dimensional arrays in Class

So I spent some time to figure out why my code wasn't working, more specifically the dynamic arrays and after testing came up with a set of rules for dynamic arrays.

c++:
/*Rules of Single Dimensional Dynamic Arrays in C++

Rule #1: Creating Dynamic Arrays

        i: When you create a dynamic array, you may declair it using #type *name = new (nothrow) #type [Size]

        ii: When you create a new dynamic array using an old variable, delete the old memory from the same variable.

        iii: Avoid creating a new dynamic array and setting it to equal another, this will create errors when trying to delete them.

Rule #2: Deleting Dynamic Arrays

        i: When you delete a dynamic array, the values will be erased, and be reused by the system

        ii: When you delete a dynamic array, you do not delete the container.

        iii: If you delete a dynamic array after setting another dynamic array to = it, data in both dynamic arrays will be deleted.

        iv: If you delete a dynamic array and then try to set another array to it, you will create a run time error.

Rule #3: Managing Dynamic Array Size

        i: When attempting to get the size of an array you can either create an integer to record array bound size, Or create a
        NULL character at the end of the array.

        ii: When resizing a dynamic array or adding a value you can simply add a value to the array name [size+1] = value; however
        this does not throw any expection to user but to windows if there is an error

        iii: When resizing a dynamic array or adding a value, you may resize the array by creating a new array to hold every value then add
        x new values, free the old dynamic array and set it to the new one, just do not delete the new dynamic array.

Rule #4 Other Trials

        i: If you delete a dynamic array with x size, then create a new dynamic array with the same size as the one deleted, you will not
        get any old values.

*/


Using these rules I can up with this:

c++:

//main.cpp
#include <iostream>
#include <new>
#include "Event.h"
using namespace std;

int main (int agrc , char * argv []){
        Event test1 = Event();
        test1.AddEvent('g',2);
        test1.AddEvent('h',22);
        test1.DispEvent();
        test1.~Event();
        //test1.DeleteEvent();

        system ("pause");
        return 0;
}



c++:
#ifndef EVENT
#define EVENT
#include <new>
#include <iostream>

using namespace std;
class Event {
public:
        Event ();
        ~Event ();
        void DeleteEvent ();
        void AddEvent (char, int);
        void DispEvent ();
private:
        char* eName;
        char* eChar;
        int* eNum;
        int eBound;
};

Event::Event (){
        eBound = 0;
        eChar = new (nothrow)char [eBound];
        eNum = new (nothrow)int [eBound];
       
}

Event::~Event(){
        eBound = 0;
        delete eChar;
        delete eNum;
}

void Event::DeleteEvent (){
        eBound = 0;
        delete eChar;
        delete eNum;
}

void Event::AddEvent (char eventChar, int eventNum){
        ++ eBound;
        char* tChar = new (nothrow) char [eBound];
        int* tInt = new (nothrow) int [eBound];
        if (tChar == 0 || tInt == 0){
                throw ("NULL");
        }
        for (int i = 0; i < eBound-1; i++){
                tChar [i] = eChar [i];
                tInt [i] = eNum [i];
        }

        delete eChar;
        delete eNum;

        tChar [eBound-1] = eventChar;
        tInt [eBound-1] = eventNum;
        eChar = tChar;
        eNum = tInt;
}

void Event::DispEvent (){
        for (int i = 0; i < eBound; i++){
                cout << eChar [i]<< "::" << eNum[i];
        }
}
#endif


The problem I am getting now is when I try to delete the dynamic array. with test1.~Event(); or test1.DeleteEvent(); it creates an error, anyone know how I can solve this?
Dreadnought




PostPosted: Thu Oct 18, 2012 6:59 pm   Post subject: Re: Multi-Dimensional arrays in Class

For a start consider using new[] and delete[] to allocate and free arrays on the heap.
TerranceN




PostPosted: Thu Oct 18, 2012 7:19 pm   Post subject: RE:Multi-Dimensional arrays in Class

Your code runs fine in g++ 4.6.1 (after I included <cstdlib> for the system function), but g++ is fine with deleting already deleted memory, and even deleting null pointers, so you should try the following.

When you create something on the stack, its destructor (~Event in this case) is called automatically when it goes out of scope. So if you call test1.~Event() manually, that method will end up being called twice, meaning you try to free memory that's already been free'd.

Also a couple things with your code you can improve:

c++:

char* tChar = new (nothrow) char [eBound];
int* tInt = new (nothrow) int [eBound];
if (tChar == 0 || tInt == 0){
        throw ("NULL");
}


What's the point of suppressing allocation errors when you create the array if you're just going to check right after? And in general if you get a null back from creating an array you're going to get a null dereference sooner or later so you might as well keep the error somewhere where it's easy to see the cause. Also IIRC those errors almost never happen unless the system is out of memory or you allocate something huge.

And you also use eChar and eNum as parallel arrays. You can just abstract that into its own class/struct and just have a list of those.

@Dreadnought:
Isn't that what's he already doing, just inside a class?
Dreadnought




PostPosted: Thu Oct 18, 2012 7:40 pm   Post subject: Re: Multi-Dimensional arrays in Class

Sorry, you're right, the code does the same thing, I'm just used to using new[] and delete[] for arrays. please disregard my previous post.
copthesaint




PostPosted: Thu Oct 18, 2012 9:53 pm   Post subject: RE:Multi-Dimensional arrays in Class

Thanks Terrance I appreciate the answer and thanks for explaining the destructor.
Display posts from previous:   
   Index -> Programming, C++ -> C++ Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 6 Posts ]
Jump to:   


Style:  
Search: