Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » 2dimensionales feld dynamisch reservieren

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
16.07.2003, 13:45 Uhr
~lucky luke
Gast


hallo,

wie kann ich in c++ mit new des machen?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
16.07.2003, 13:48 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


Hi;


C++:
int i,x_dim=20,y_dim=10;
double **2d_array;

2d_array=new double*[x_dim];
for(i=0;i<xdim;i++) 2d_array[i]=new double[y_dim];

//mit dem feld arbeiten und am ende freigeben nicht vergessen
for(i=0;i<xdim;i++) delete [] 2d_array[i];
delete [] 2d_array;




Gruss Heiko
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
16.07.2003, 15:03 Uhr
~lucky luke
Gast


dankeschön!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
16.07.2003, 15:29 Uhr
0xdeadbeef
Gott
(Operator)


Wahlweise auch

C++:
double *feld = new(double[xdim][ydim]);
//...
delete[] feld;


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
16.07.2003, 15:48 Uhr
~lucky luke
Gast


@beefy, bei mir nimmt er des nicht an!

cannot convert...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
16.07.2003, 15:52 Uhr
0xdeadbeef
Gott
(Operator)


Ja, kein Wunder. Ich hab mich verdacht, das kann garnicht hinhauen. Vergiß, dass ich das gesagt habe...
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
16.07.2003, 16:17 Uhr
virtual
Sexiest Bit alive
(Operator)


Mit

C++:
double* array = new double[dim_x*dim_y];


Wird ein halber Schuh draus.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
16.07.2003, 16:38 Uhr
virtual
Sexiest Bit alive
(Operator)


Ein dahingesauter 60%iger Schuh:

C++:
template<typename T, int X, int Y>
class Array2D
{
private:
    typedef T array_type[X][Y];
private:
    array_type data;

public:
    class proxy
    {
    private:
        array_type& data;
        int x;
    public:
        proxy(array_type& data_, int x_) :data(data_), x(x_) { };
        T& operator [] (int y) { return data[x][y]; };
    };

public:
    proxy operator [] (int x) { return proxy(data,x); }
};


int main()
{
    Array2D<double,10,20> a;

    a[9][19] = 19;
}


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
16.07.2003, 17:28 Uhr
Tommix



Hallo,
@virtual:
Visual C meckert bei Deinem Code bei "array_type& data;" 'Verweis auf ein Feld der Groesse Null ist ungueltig"'. Ich bin mir aber gerade bei templates in Zusammenhang mit diesem Compiler nie so ganz sicher, wie falsch die Fehler sind.

Eigentlich wollte ich was anderes, sozusagen als Zusatzfrage (liegt schon ewig in der Schublade und war mir nie einen eigenen Thread wert). Ich wollte schon immer mal eine zweidimensionale Arrayklasse machen, mit der man wie mit einem "normalen" Feld arbeiten kann (var[x][y]), bei der aber die Indizes auf Gültigkeit geprüft werden. Nach dem Motto: Langsam aber sicher.
Ich bin bis hierhin gekommen:

C++:
#ifndef NULL
#define NULL 0
#endif

class CMatrixException
{
public:
    enum TCause
    {
        NoError = 0,
        Memory,
        Bounds
    };

private:
    TCause m_cause;

public:
    CMatrixException(TCause cause)
    :   m_cause(cause)
    {}

    virtual ~CMatrixException()
    {}

};

template<class TYPE>
class CMatrix
{
public:
    CMatrix(TYPE zero = static_cast<TYPE>(0));
    CMatrix(int xSize, int ySize, TYPE zero = static_cast<TYPE>(0));
    virtual ~CMatrix();

    void SetSize(int xMax, int yMax, bool preserve = true);
    void SetAll(TYPE value);
    void Clear() {SetAll(null);}
    void SetAt(int x, int y, TYPE value);
    TYPE GetAt(int x, int y) const;
    TYPE* operator[] (int y) const;

private:
    void SetAll(TYPE* ptr, TYPE value, int elements);
    TYPE& At(int x, int y) const;
    TYPE* m_pElements;

    int m_xMax;
    int m_yMax;

    const TYPE null;
};

#define Error(cause) throw new CMatrixException(cause)

//  Interface

template <class TYPE>
CMatrix<TYPE>::CMatrix(TYPE zero)
:   m_pElements(NULL),
    m_xMax(0), m_yMax(0),
    null(static_cast<TYPE>(zero))
{
}

template <class TYPE>
CMatrix<TYPE>::CMatrix(int xSize, int ySize, TYPE zero)
:   m_pElements(NULL),
    null(static_cast<TYPE>(zero))
{
    SetSize(xSize, ySize, false);
}

template <class TYPE>
CMatrix<TYPE>::~CMatrix()
{
    delete[] m_pElements;
}

template <class TYPE>
void CMatrix<TYPE>::SetSize(int xSize, int ySize, bool preserve)
{
    if((xSize <= 0) || (ySize <= 0))
    {
        Error(CMatrixException::Bounds);    // negative bounds
    }
    else
    {
        TYPE* pData = new TYPE[xSize*ySize];

        if (pData)
        {
            SetAll(pData, null, xSize*ySize);
            
            if (preserve)
            {
                int xMax = xSize < m_xMax ? xSize : m_xMax;
                int yMax = ySize < m_yMax ? ySize : m_yMax;

                //.. Kopieren
                for (int y = 0; y < yMax; ++y)
                {
                    TYPE* pSrc = m_pElements+(y*m_xMax);
                    TYPE* pDst = pData+(y*xMax);

                    for (int x = 0; x < xMax; ++x)
                    {
                        *(pDst++) = *(pSrc++);
                    }
                }
            }

            m_xMax = xSize;
            m_yMax = ySize;

            delete m_pElements;
            m_pElements = pData;
        }
        else
        {
            Error(CMatrixException::Memory);    // new failed
        }
    }
}

template <class TYPE>
void CMatrix<TYPE>::SetAll(TYPE value)
{  
    SetAll(m_pElements, value, m_xMax*m_yMax);
}

template <class TYPE>
void CMatrix<TYPE>::SetAt(int x, int y, TYPE value)
{
    At(x, y) = value;
}

template <class TYPE>
TYPE CMatrix<TYPE>::GetAt(int x, int y) const
{
    return At(x, y);
}

template <class TYPE>
TYPE* CMatrix<TYPE>::operator [] (int y) const
{
    return &At(0, y);
}

template <class TYPE>
void CMatrix<TYPE>::SetAll(TYPE* ptr, TYPE value, int elements)
{
    for (int index = 0; index < elements; ++index)
        *(ptr++) = value;
}

template <class TYPE>
TYPE& CMatrix<TYPE>::At(int x, int y) const
{
    if ((x < 0) || (x >= m_xMax) || (y < 0) || (y >= m_yMax))
        Error(CMatrixException::Bounds);
    else
        return m_pElements[y*m_xMax+x];
}

#undef Error




class CDoubleMatrix : public CMatrix<double>  
{
public:
    CDoubleMatrix();
    CDoubleMatrix(int xSize, int ySize);
    virtual ~CDoubleMatrix();

};

CDoubleMatrix::CDoubleMatrix()
:   CMatrix<double>(0.0)
{
}

CDoubleMatrix::CDoubleMatrix(int xSize, int ySize)
:   CMatrix<double>(xSize, ySize, 0.0)
{
}

CDoubleMatrix::~CDoubleMatrix()
{
}

#include <iostream>

int main()
{
    CDoubleMatrix matrix(10, 10);
        
    matrix.SetAt(3, 3, 1.234);
    matrix[3][4] = -2.345;
    std::cout << matrix.GetAt(3, 3) << std::endl;
    std::cout << matrix[3][4] << std::endl;

    try
    {
        matrix[11][1];  // wird abgefangen
        matrix[1][11];  // wird nicht abgefangen
    }
    catch(CMatrixException* pException)
    {
        std::cerr << "Error" << std::endl;
        delete pException;
    }

    return 0;
}


(Durch das viele rumprobieren ist vermutlich etlicher Müll mit drin.)
Wie man am Ende sieht, wird der erste Index geprüft und der zweite nicht.

Hat einer 'ne Idee?
Falls das zu leicht ist: Wie kann man dieses Methodik auf beliebig viele Dimensionen erweitern?

Gruss, Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
16.07.2003, 18:58 Uhr
virtual
Sexiest Bit alive
(Operator)


@Tommix:
Daß es sich nicht mit dem VC compileren Läßt macht mich zwar traurig, bestätigt mich aber in der Auffassung, dass dies ein Schrottkram ist und ne Schweinerei, daß die geld dafür nehmen. Was ich geschrieben habe, ist legaler C++ Code.

Daß die Zweite Dimension nicht geprüft wird, hat einen einfachen Hintergrund. Folgende Fragmente sind identisch

C++:
matrix[1][11]



C++:
double* v= matrix[1]
v[11]


Wie man sieht gibt der op[] von matrix einfach einen Pointer auf ein double zurück. Arrayzugriffe können nicht ge-range-checkt werden. Diesen Umstand verdankt die Klasse proxy in meinem Beispiel seine Existenz, weil man in den op[] von Array2D und proxy auch noch problemlos einen RangeCheck unterbringen kann. Vernünftigen Compiler vorausgesetzt .
Im realen Leben würde ich aber wohl am ehesten Valarrays verwenden.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: