0

I am learning c++ pointers. I wrote some code to see if I understood correctly.

It might look a little weird. I made it a little complex on purpouse. Could you please tell me If I understood correctly? Or if there is something wrong that I didn't understand?

#include <iostream>

using namespace std;

int main()
{
    int **x = new int*[20];
    *x      = new int [5]; //x[0] ==>[0,0,0,0,0]
    *(x+1)  = new int [3]; //x[1] ==>[0,0,0] 

    *x[0]     = 10; //x[0][0] = 10
    *(x+1)[0] = 20; //x[1][0] = 20

    cout << x[0][0] << endl;
    cout << x[1][0] << endl;

    delete [] *x;
    delete [] *(x+1);
    delete [] x;

    return 0;
}
6
  • 1
    It looks like you understand what you did. Commented Aug 13, 2018 at 16:48
  • When used with pointers, arr[x] is equivalent to *(arr + x) and arr[0] is equivalent to *arr. I see nothing wrong here except mixed styles. Commented Aug 13, 2018 at 16:48
  • all fine except nobody would write code like this now. Normal case is to use std::vector Commented Aug 13, 2018 at 16:49
  • ...or std::array. Commented Aug 13, 2018 at 16:50
  • 3
    We have got no idea what you understood. The posted code is free from undefined behavior, and code matches comments. This is as much as I can tell. Commented Aug 13, 2018 at 16:51

3 Answers 3

4

Due to operator precedence, the lines

*x[0]     = 10;
*(x+1)[0] = 20;

are equivalent to

*(x[0])     = 10;
*((x+1)[0]) = 20;

I am not sure whether you meant that. IMO, it will be better to use:

(*x)[0]     = 10;
(*(x+1))[0] = 20;
Sign up to request clarification or add additional context in comments.

1 Comment

I meant the last one. Because What I wanted to say is that x[0][0] = 10 and x[1][0] = 2. I have to work on operator precedence as WhozCraig advised
2

As best as I'm able to determine, your code is correct with respect to what your comments expect is happening, prevents memory leaks, and is free of Undefined Behavior, which is all fine and good.

But consider, for a second, how much unnecessary boilerplate code you had to write to make this work. And then consider the following code using std::unique_ptr, which is exactly identical to your code in terms of behavior, but removes the boilerplate that is responsible for deleting the memory, by using a class which handles that behavior automatically:

#include<memory>

int main()
{
    auto x = std::make_unique<std::unique_ptr<int[]>[]>(20);
    x[0] = std::make_unique<int[]>(5); //x[0] ==>[0,0,0,0,0]
    x[1] = std::make_unique<int[]>(3); //x[1] ==>[0,0,0] 

    *x[0]     = 10; //x[0][0] = 10
    //This will no longer compile because, while technically correct, this kind of pointer arithmetic
    //is inherently unsafe and prone to mistakes
    //*(x+1)[0] = 20; //x[1][0] = 20
    x[1][0] = 20;

    cout << x[0][0] << endl;
    cout << x[1][0] << endl;

    //No more deletes needed; `std::unique_ptr` manages its own memory and deletes when needed

    return 0;
}

Now consider the next code, which simplifies further by using a more robust idiom for dynamically-sized arrays, std::vector:

#include<vector>

int main()
{
    std::vector<std::vector<int>> x(20);
    x[0].resize(5); //x[0] ==>[0,0,0,0,0]
    x[1].resize(3); //x[1] ==>[0,0,0] 

    x[0][0] = 10;
    x[1][0] = 20;

    cout << x[0][0] << endl;
    cout << x[1][0] << endl;

    return 0;
}

This is a pretty clear case-study in why, for most purposes, you should prefer things like std::unique_ptr<T[]> or std::vector<T> for describing "Arrays of T". And for 2d arrays, std::unique_ptr<std::unique_ptr<T[]>[]> or std::vector<std::vector<T>>, which describe the same semantics as your original code.

Comments

0

The only incorrect thing is, new int[] does not initialize its memberes. After *x=new int[5], x can be {123,456,789,-123,-456} or anything else.

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.