1

i need an array at runtime to hold some x-y coordinate data. It may be anywhere from a few dozen points to several thousands. So, to be efficient i'd like to allocate the array at runtime. I found an example but i can't extend it. Here is what i have now:

double *A;
A = new double[NumSamp];  // NumSamp is an int set in earlier code at runtime
for (int y = 1; y < NumSamp ; y++) {
       A[y] = y;
}
delete [] A;
A = NULL;

This code works fine, but when i try to change to two dimensions i get E2034 Cannot convert double( *)[2] to double*. Here is the line i changed that caused the error:

A = new double[NumSamp][2];

How should i be doing this? I'm working in C++Builder (10.3.1) and will target Win32, iOS, and Android.

M.M
  • 138,810
  • 21
  • 208
  • 365
relayman357
  • 793
  • 1
  • 6
  • 30
  • That is because double *A is not the correct type. – Tagger5926 Aug 19 '19 at 01:55
  • May be a duplicate of this actually: https://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new A lot of people were concerned with the performance and storage issues with using [][] and instead they suggest creating a class that wraps a 1d array which can be accessed like a 2d array. – Tagger5926 Aug 19 '19 at 02:42
  • Tagger5926 I saw that post but I wasn’t sure if there wasn’t an easier way (plus I’m a novice). I’ll see what I can do with that – relayman357 Aug 19 '19 at 02:49
  • If that is the case, then choose what is the most readable and easier to use. Once you got something working and you have issues with performance or strict storage requirements you can update your question accordingly. – Tagger5926 Aug 19 '19 at 02:54
  • 1
    @relayman357 your `vector` code needs to call `A.resize(NumSamp);` instead of `A.reserve(NumSamp);`. You are not actually pushing any elements into the vector, so your use of `operator[]` is undefined behavior. See [std::vector::resize() vs. std::vector::reserve()](https://stackoverflow.com/questions/13029299/). Also, your final solution should have been posted (if at all) as a separate answer, not as an edit to your question. – Remy Lebeau Aug 20 '19 at 21:59
  • Thanks Remy. I'll modify my code to use `.resize()` and post it as answer. I've been using `.reserve()` without issue during testing. Probably would have found that undefined behavior the hard way later. – relayman357 Aug 21 '19 at 00:03
  • My code stopped working when i changed to `.resize()`. I'm working to debug and see where breaking down. My latest working code is UPDATE 2. – relayman357 Aug 21 '19 at 00:13
  • I think my code was having a problem with my intermediate steps to calculate the float values. I had a double array doing a bunch of work, and elements from that double getting poked into my vector as TPointF values. Anyway, both `.resize()` and `.reserve()` work equally as well in my code. After reading the post you referenced i don't see how either code use would be wrong. I'll keep reading it though... – relayman357 Aug 21 '19 at 00:42
  • This site uses a Question and Answer format -- you should not post solutions in the Question box. You can instead post the fixed code in the Answer box if you like – M.M Aug 21 '19 at 03:11

1 Answers1

2

In your example, you firstly forgot to update the type of the array. It is no longer double * but actually double **. Try to keep the declare and the initialization on the same line to avoid these problems. i.e. double **A = new double*[NumSamp];

Also, you can't allocate dynamic memory like that for a 2d array. Try the following.

int main()
{
    int const Y_VAL = 1;
    int const X_VAL = 0;
    // declare array as a 2d array
    double **A;
    // Allocate memory for main array
    A = new double*[NumSamp]; 
    // allocate memory for each sub array
    for (int y = 0; y < NumSamp ; y++) {
       A[y] = new double[2];
    }

    for ( int y = 0; y < NumSamp; ++y) {
        A[y][Y_VAL] = 4; // Initialize X and Y values
        A[y][X_VAL] = 4;
    }    



    // free memory
    for (int y = 0; y < NumSamp ; y++) {
        delete[] A[y];
    }
    delete [] A;
    A = NULL;
}

Also, the second array seems to be static. Why not just create a struct and use vector since they are can be dynamic. e.g.

struct Data
{
    double x, y;
    // Constructor with initializer list to initialize data members x and y
    Data( double const _x, double const _y ) : x(_x), y(_y){}
};

int main()
{
    std::vector<Data> A;
    A.reserve(NumSamp); // reserve memory so it does not need to resize the capacity
    for(auto a : A)
    {
         a.emplace_back( 2, 5 ); // Initialize all "Data" with x=2, y=5;
    }
    // access data
    for(auto a : A)
    {
        std::cout << a.x << ":" << a.y << '\n';
    }
    std::cout << std::endl;
}
Tagger5926
  • 442
  • 3
  • 13