0

Please help me, i'm not being able to understand how this code is working. I just can't seem to visualize it in my head. An elaborative explanation could save me the trouble of being a failure in life in the future.Thank you.

int **data = new int*[row];

    for(i=0;i<row;i++)
        data[i] = new int[col];

    for(i=0;i<row;i++)
    {
        for(j=0;j<col;j++)
        {
            data[i][j] = rand() % u;
        }
    }
  • Sidenote: [How to do a simple 2D array in C++](https://stackoverflow.com/a/2076668/4581301) This is cache friendly and handles the memory management for you. – user4581301 Sep 27 '18 at 21:51
  • if you can't visualize it in your head ,use pen and paper (the ancient method) – engf-010 Sep 27 '18 at 21:56
  • ***Never write code like this and you will be a better programmer*** Unfortunately academic institutions force students to write code like this before they let them use the standard library. – drescherjm Sep 27 '18 at 22:05
  • "Never write code like this" ,Nevertheless a c++ programmer must be able to read and understand such code (unfortunately !) – engf-010 Sep 27 '18 at 22:09
  • That said, If you find yourself in working in a shop where code frequently looks like this, keep an eye out for a soft exit or ask for more money and sort this crap out. – user4581301 Sep 27 '18 at 23:10
  • the thing is there is lots of code out there that isn't transformed to 'modern c++' yet. And when that is going to get handled ,some/many poor souls must deal with this kind of code (embedded legacy code). – engf-010 Sep 28 '18 at 01:22
  • @engf-010 embedded code nearly never uses new expression, they used some factories that interface to pools. Thing is, it almost never a good decision to 'upgrade" embedded code to ISO library (it might be not even available) – Swift - Friday Pie Sep 28 '18 at 05:45
  • That or `new` is overloaded to serve objects drawn from these pools. – user4581301 Sep 28 '18 at 20:25
  • I'm sorry. i had to ask here as i got barred from posting questions for 6 days. But please can you tell me if the below code is wrong. i think my teacher put RT as class so that we get confused. i think there should be istream& instead of RT .am i right? friend RT operator>>(istream& in, MatrixOfComplex&); – Zahin Zaman Sep 30 '18 at 09:43
  • Also i'm confused about which books to start reading to understand and eventually master the C++ language. I know from you guys' profile that you guy are experianced and have been doing this for a lot of years and are experts in c++ but i'm barely just starting right now. Anyways thanks. – Zahin Zaman Sep 30 '18 at 09:47

3 Answers3

2
#include <cstddef>  // std::size_t
#include <cstdlib>  // std::srand(), std::rand()
#include <ctime>    // std::time()

int main()
{
    // Initialize the random number generator with the current time.
    // If you don't, std::rand() behaves as if std::srand(1) had been called.
    std::srand(static_cast<unsigned>(time(nullptr)));

    std::size_t rows =  5;
    std::size_t cols = 10;
    int u = 100;

    int **data =  // data is a pointer to a pointer to int
        new int*[rows];  // allocates an array of type int* with size of row
                         // and return a pointer to it

    for (std::size_t i = 0; i < rows; i++)
        data[i] =  // every pointer in that array is assigned
            new int[cols];  // a pointer to an array of type int with size col

    for (std::size_t i = 0; i < rows; i++)  // walk through the (int**) in data
    {
        for (std::size_t j = 0; j < cols; j++)  // walk through the (int*) in data[i]
        {
            data[i][j] = std::rand() % u;  // access the j th int in data[i]
        }
    }

    // free the memory, when you are done using it *):
    for (std::size_t i = 0; i < rows; i++)
        delete[] data[i];
    delete[] data;
}

*) Better: Use smart pointers such as std::unique_ptr and std::shared_ptr so you don't have to care about resource management:

#include <memory>

// ...

auto data = std::make_unique<std::unique_ptr<int[]>[]>(rows);

for (std::size_t i = 0; i < rows; i++)
    data[i] = std::make_unique<int[]>(cols);

Even better: Use Containers like std::vector or std::deque.

Swordfish
  • 12,971
  • 3
  • 21
  • 43
  • Good answer. Sidenote: `std::deque` is optimized for easy addition to and removal from both ends. It's an excellent solution for different problems, but I wouldn't use one at the backbone for a matrix unless the matrix was very fluid in size. – user4581301 Sep 27 '18 at 21:55
0
// "int **data": declare a variable that store address of anthor address storing variables i.e. declare a pointer(*) to anther pointer(*)
// [addr of *data](data)-->[addr of **data](*data)-->[actual value](**data)
// "int **data = new int*[row]": initialize data with address of the first
// element(which is again a pointer) of the array of length 'row' and int*
// indicates that this array is an array of integer pointers(i.e. each element in this array stores address of another 1-D array containing integers.)
int **data = new int*[row];

// Now traverse through each element of the array whos address is stored
// in the data variable i.e. if you do printf(data), it will print out the
// the address of the first element of this array pointed by data. While traversing, initialize each element of this array with addresses of new array(hence data points to array and each element in this array points to another array forming a 2-D array or matrix)
for(i=0;i<row;i++)
    data[i] = new int[col];

// Rest should be obvious.
for(i=0;i<row;i++)
{
    for(j=0;j<col;j++)
    {
        data[i][j] = rand() % u;
    }
}

// Feel free to ask questions if this still does not make sence.
// Also my C knowledge is a bit rusty so corrections are always welcome.
Karan Bhagat
  • 329
  • 1
  • 6
0

a pointer is essentially a variable which contains a memory address of an object. Type of an object in your case is 'int'.

memory:

00000000: [some value] -- start
...
pointer : [address1] pointer to int (int*) +
...                                        |
address1: [value of int] <-----------------+

now what you have is int** which is a pointer to pointer to int.

memory:

00000000: [some value] -- start
...
pointer : [address1] pointer to int (int**) ----+
...                                             |
address1 : [address2] pointer to int (int*) + <-+
...                                         |
address2: [value of int] <------------------+

Now, what you did, you allocated an array of pointers to int of size row

  memory:

00000000: [some value] -- start
...
pointer : [address1] pointer to int (int**) -----+
...                                              |
address1 : [address-a] pointer to int (int*) + <-+
address2 : [address-b] pointer to int (int*) 
address3 : [address-c] pointer to int (int*) 
address4 : [address-d] pointer to int (int*) 
address5 : [address-e] pointer to int (int*) +
...                                          |
address-e: [value of int] <------------------+
...
address-b:...

hope it helped

Serge
  • 11,616
  • 3
  • 18
  • 28