-3

Apparently I'm misunderstanding this, but I'm trying to simply set specific numbers to a dynamic memory array.

#include <iostream>
#include <cstdlib>
using namespace std;

int main () {
    int *arr = new int [4][5]
    {{3, 6, 9, 23, 16}, 
    {24, 12, 9, 13, 5},
    {37, 19, 43, 17, 11},
    {71, 32, 8, 4, 7}};

    cout<< arr [1][3]<< endl<< endl;
    int *x = new int;
    *x = arr [2][1];
    cout<< x<< endl;
    cout<< *x<< endl << endl; 
    delete x;
    *x = arr [0][3];
    cout<< x<< endl;
    cout<< *x<< endl;
    delete x;
    delete [] arr;
    return;
}
halfer
  • 19,824
  • 17
  • 99
  • 186
  • I don't even know how to post the code right, apparently. – user9076567 Dec 09 '17 at 14:09
  • Recommended read: https://stackoverflow.com/questions/46991224/are-there-any-valid-use-cases-to-use-new-and-delete-raw-pointers-or-c-style-arr – user0042 Dec 09 '17 at 14:11
  • 3
    What do you want to do with this code? You are using `new` which makes everything very complicated. You `delete` memory and then access it and then `delete` it again. Very broken. And then you wrote `return;` which should not compile because you need to `return` an `int` or leave out the `return` completely. – nwp Dec 09 '17 at 14:12
  • 2
    Welcome to Stack Overflow. Please read [What topics can I ask about here?](https://stackoverflow.com/help/on-topic) and [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask) – klutt Dec 09 '17 at 14:24
  • 1
    _@user9076567_ As @klutt says. Especially the part that you should put an actual question in your post. – user0042 Dec 09 '17 at 14:27
  • 1
    The first `delete x` is obviously wrong. `x` is still used after that `delete`. Also `x` is deleted twice which is UB (undefined behavior). Also, you don't need dynamic allocation in this simple program. – Phil1970 Dec 09 '17 at 14:43

2 Answers2

1

C++ support for multidimension arrays is done through libraries (eg boost). Without classes it really only understands 1D arrays, particularly when you are using pointers, which C/C++ really sees as just a pointer to the first element of the array. To get your example to work without classes you need to define a type that holds one row and then create an array of that type, which you can assign values to as you show.

#include <iostream>
#include <cstdlib>
using namespace std;

int main () {
    typedef int row_t[5];
    row_t *arr = new row_t[4] {{3, 6, 9, 23, 16}, 
    {24, 12, 9, 13, 5},
    {37, 19, 43, 17, 11},
    {71, 32, 8, 4, 7}};

    cout<< arr[1][3] << endl<< endl;
    int *x = new int;
    *x = arr [2][1];
    cout<< x<< endl;
    cout<< *x<< endl << endl; 

    *x = arr [0][3];
    cout<< x<< endl;
    cout<< *x<< endl;
    delete x;
    delete [] arr;
    return 0;
}

Alternatively you can project the 2D array onto a 1D array as:

#include <iostream>
#include <cstdlib>
using namespace std;

int main () {
    int *arr = new int[20] {3, 6, 9, 23, 16, 
    24, 12, 9, 13, 5,
    37, 19, 43, 17, 11,
    71, 32, 8, 4, 7};

    cout<< arr[5*1+3] << endl<< endl;
    int *x = new int;
    *x = arr [5*2+1];
    cout<< x<< endl;
    cout<< *x<< endl << endl; 

    *x = arr [5*0+3];
    cout<< x<< endl;
    cout<< *x<< endl;
    delete x;
    delete [] arr;
    return 0;
}

To get 2D indexing with dynamic data use something like boost::multi_array

#include <iostream>
#include <boost/multi_array.hpp>
using namespace std;

int main () {
    boost::multi_array< int, 2 >arr(boost::extents[4][5]);
    int tmp[] { 3, 6, 9, 23, 16, 
      24, 12, 9, 13, 5,
      37, 19, 43, 17, 11,
      71, 32, 8, 4, 7 };
    arr = boost::multi_array_ref< int, 2 >( &tmp[0], boost::extents[4][5] );

    cout<< arr [1][3]<< endl << endl;
    int *x = new int;
    *x = arr [2][1];
    cout<< x<< endl;
    cout<< *x<< endl << endl; 
    *x = arr [0][3];
    cout<< x<< endl;
    cout<< *x<< endl;
    delete x;
    // delete [] arr;
    return 0;
}
Justin Finnerty
  • 329
  • 1
  • 7
  • PS: `endl` inserts a `flush` of the stream which makes your code potentially very slow. Use `\n` instead. – Justin Finnerty Dec 09 '17 at 15:25
  • Well done. Can you throw in an admonition about using operator new? – Jive Dadson Dec 09 '17 at 16:01
  • Wow! Thank you very much, that was driving me crazy. I knew there was something I wasn't understanding. I hadn't even considered defining a new type for this. Teaching myself C++ has turned out to be quite a challenge, you rock! – user9076567 Dec 10 '17 at 04:21
  • @Jive Dadson, other people commented on using `new` and I wanted to give examples which had a minimal change for the original code. – Justin Finnerty Dec 11 '17 at 10:06
1

Using operator new is tricky. Your program has a number of errors regarding the use of new and delete. There is a standard implementation of dynamic arrays that hides all the trickiness and cleans up after itself, namely, std::vector. Also, avoid the use of "using namespace std;" You can get puzzling name conflicts that way.

Works good --

#include <iostream>
#include <cstdlib>
#include <vector>

using std::cout;
using std::endl;
using std::vector;

int main () {
    vector<vector<int>> arr 
    { { 3, 6, 9, 23, 16 },
    { 24, 12, 9, 13, 5 },
    { 37, 19, 43, 17, 11 },
    { 71, 32, 8, 4, 7 } };

    cout<< arr[1][3]<< endl<< endl;
    int x = arr[2][1];
    cout<< x<<  endl;
    cout<< x<< endl << endl;
    x = arr[0][3];
    cout<< x<< endl;
    return 0;
}

P.s. There's nothing dynamic about the way you used arr. You could have instead declared it thus:

int arr[4][5] 
{ { 3, 6, 9, 23, 16 },
{ 24, 12, 9, 13, 5 },
{ 37, 19, 43, 17, 11 },
{ 71, 32, 8, 4, 7 } };
Jive Dadson
  • 16,680
  • 9
  • 52
  • 65
  • I know I wasn't properly using the memory dynamically, I didn't get that far in the code when I hit this snag. I honestly haven't even learned what vectors are yet. What's wrong with using namespace std; ? – user9076567 Dec 10 '17 at 04:26
  • @user9076567 The question is not what is wrong with `using namespace std`, but why did we introduce namespaces into C++. When you understand that you will stop including namespaces, particularly at global scope. @Jive Dadson's example of `using` individual functions is much safer. Better would be to put the `using` statements into the `main` function to reduce the scope of the statements further. – Justin Finnerty Dec 11 '17 at 10:04
  • Note that there may be significant differences between the multi_array, int[] examples I gave the `int arr[4][5]` here and using `vector>` or the `typedef ... row_t`. That is in the memory layout of the data in memory. The multi_arry, int[] and int[][] will have single consecutive block of ints. The `vector>` will have each row in a separate memory location. The row_t example *may* pack the row_t objects consecutively or pad them for memory alignment (here that is unlikely but may occur for arrays of characters). – Justin Finnerty Dec 11 '17 at 10:15