2

I'm trying to initialise a jagged array. Why doesn't this work:

int *arr[10]; for (int *row : arr) row = new int[10]; 

it runs but then arr is unreadable.

How can I use this form of "for" properly in this situation?

Otherwise how can I just initialise a jagged array of X rows, each row is Y elements and set all to zero?

2
  • 10
    While it does not explain why it does not work, for Finagle's sake, just use std::vector. Commented Apr 29, 2013 at 11:40
  • 6
    That has way too many stars to be C++. Commented Apr 29, 2013 at 11:42

3 Answers 3

7

Try:

int* arr[10]; for (int*& row : arr) row = new int[10]; 

Since you are changing the value in the array inside of the loop you need to iterate over references instead of values (which are only copies of what was in the array). This is very similar to function call semantics.

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

5 Comments

damn !, I was doing (int&* row: arr) instead ! should have thought of switching the order... thanks
No, you should've thought of not using raw pointers and C-style arrays.
int &* row IIRC is the illegal and nonsensical pointer to reference to int.
@Spacemonkey You could use (auto& row : arr) instead
@Spacemonkey C++ does not allow pointers to references (e.g., int &*).
1
for(auto&row:arr) // note the &. also note the auto row = new int[10]; 

the compilers should really warn about this stupid error. Happened to me many times.

Comments

0

The provided answer by filmor is correct, but as others have already stated in the comments: If you really want to learn C++11 you should use a container like std::vector.

For example:

std::vector<std::vector<int>> list; 

And you're done. You can add as many ints as you like. If you want to have a fixed size list of dynamic int-lists, consider using std::array:

std::array<std::vector<int>, 10> arr; 

Although I would always recommend using std::vector if performance or memory is not an issue. You have to make sure you're not exceeding the maximum number of elements anyway.

Concerning the for-loop, I would always try to use it this way:

for (auto &item : list) 

If you don't want to modify the list, add const:

for (const auto &item : list) 

Even if you don't want to modify the list, you're not making copies as you progress through it.

10 Comments

auto const&, because const is best placed on the right-hand side for consistency's sake (it can only be placed on the left-hand side for the outermost level which is awfully confusing)
if I don't care about performance, I wouldn't even use C++ at all.
@MatthieuM. I think that's mostly a matter of taste and only leads to endless discussions as to what's right and what's wrong.
@Excelcius: in general, I don't care much about such issues (indentation, placement of braces, etc...); however in this case left-hand side placement can really be confusing. For example, consider a template method void foo(const T&). If T is int, then you have a const int& which is a const-reference to an int and everything is well. If T is int*, then you have a const int*& which is a const-reference to an int*, that is the pointer is const, not int, even though const is closer to int and you read const, int, pointer...
@Excelcius: ... now write T const& and substitute int* for T. You then have int* const&, same type as const int*&, put it reads (from right to left) const-reference to pointer to int, which is exactly what it is. Of course, for an experienced developer it's just a quirk to be accounted for, but for a newcomer to the language, the inconsistency is utterly baffling.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.