2

I need to create a structure that holds a variable number of 'char[2]'s, i.e. static arrays of 2 chars.

My question is, how do I allocate memory for x number of char[2].

I tried this (assuming int x is defined):

char** m = NULL;
m = new char[x][2];
...
delete [] m;

(it didn't work)

I realise I could use std::vector<char[2]> as a container, but I'm curious as to how it would be done with raw pointers.

I am very new to C++ and trying to learn.

4 Answers 4

4

In your code, the type of 'm' doesn't match your 'new' call. What you want is:

char (*m)[2] = NULL;
m = new char[x][2];
...
delete [] m;

m is a pointer to arrays of 2 chars, and you call new to get an array of x arrays of 2 chars and point m at the first one.

Sign up to request clarification or add additional context in comments.

3 Comments

@j_random_hacker, It's a "pointer to array of 2 chars". No array of them. "array of pointer to array of 2 chars" looks like char (*m[N])[2];, and could be used if you did N independent such new calls :) +1 @Chris xD
You're absolutely right -- how did I mess that up?! I've deleted that misleading comment.
+1. Though it's often easier to use a typedef: typedef char char2[2]; char2 *m = new char[x][2];
4

I believe that the following code is more readable than char[n][2]:

typedef char wchar[2];   // array of two chars
const size_t n = 100;    // some const
wchar* x = new wchar[n]; // array of wchars, where wchar is array of two chars

// here is still a problem that you could write the following
x[5][5] = 0;             // not what you expected?

delete[] x;              // clean up

If we aware of the internal structure of wchar, the code will be more readable if we declare it as follows:

// using struct is just gives names to chars in wchar, without performance drop
struct wchar {
  char h;
  char l;
};

...

const size_t n = 100;    // some const
wchar* x = new wchar[n]; // array of wchars

x[0].h = 0;
x[0].l = 0;

delete[] x;              // clean up

And finally, because we use C++, no need to use C arrays:

const size_t n = 100;    // some const   
typedef std::tr1::array<wchar, n> my_arr;
my_arr* x = new my_arr;

(*x)[0].h = 0;
(*x)[0].l = 0;

delete x;

One more pretty safe option with compile time range checking:

template<int n_max>
struct array_n {
    char v[2*n_max];

    template<size_t n, size_t s> 
    char& get() {
        BOOST_STATIC_ASSERT( s < 2 );
        BOOST_STATIC_ASSERT( n < n_max );
        return v[n*2+s];
    };  
};

int main( int argc, char**argv)
{
    const size_t n = 100;    // some const   
    typedef array_n<100> my_arr;
    my_arr* x = new my_arr;

    x->get<10, 1>() = 0;   // ok
    x->get<50, 0>() = 0;   // ok
    x->get<10, 2>() = 0;   // compile time error
    x->get<500, 0>() = 0;  // compile time error

    delete x;
}

3 Comments

Nice. One thing to be aware of with the typedef approach is that if you happen to allocate a single wchar (not an array of wchar -- e.g. wchar* m = new wchar;), you must still delete it with delete [] m;. litb noticed this ugly hole in another thread.
Thanks for your answer. Those are all easier ways to do it.
@j_random_hacker, that's why to use struct is more preferable.
0

You would end up determining the size of the array, and then use new, and treat it as a two-dimensional array.

But, for a good discussion on this you may want to look at: http://www.velocityreviews.com/forums/t283481-dynamic-multidimensional-arrays.html

Comments

0
unsigned x=10;
typedef char A2[2];
A2 *m=new A2[x];
m[0][1]='a';
m[9][0]='b';
delete[] m;

C multi-dimensional arrays (where all but the first dimensions are constant) are laid out contiguously.

If you want a (potentially jagged) multi-dimensional array which is a 1d array of 1d arrays, then you have to loop:

  char **m=new char *[x];
  for (unsigned i=0;i<x;++i) m[i]=new char[2];
  ...
  for (unsigned i=0;i<x;++i) delete[] m[i];
  delete[] m;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.