2

(Note: I'm currently learning C++, so if there is a better way to do what I am doing, explanations would be helpful.)

I am making Conway's Game of Life in C/C++ and have the following code:

bool ** previous;
bool ** current;

void init() {
    previous = new bool*[width];
    current = new bool*[width];
    for (int i =0; i < width; i++) {
        previous[i] = new bool[height];
        current[i] = new bool[height];
    }
}

The reason for the dynamic arrays is that the width and height are given by the user at runtime. If I had one-dimensional arrays, I could do the following:

bool * previous;
bool * current;

void () {
    bool * temp = current;
    current = previous;
    previous = temp;
}

However, this approach does not work as hoped with the two-dimensional array. As it is technically an array of arrays, do I have to swap each sub-array pointer individually? Is there a better way to go about defining multi-dimensional arrays and swapping them?

Edit: I have yet to really use any C++ specific features, so if I can do this in pure C, I'd prefer that.

Leagsaidh Gordon
  • 1,641
  • 5
  • 19
  • 28
  • I was just adding a note as you commented. As I'm learning, an answer for both would be the most useful to me (and anyone else who stumbles across this question on their searches), but I'm looking mainly at C. – Leagsaidh Gordon Nov 02 '12 at 14:24
  • There is no such thing as C/C++. It's either one or the other as Denis says. I don't know why you'd want to go pure C for this if you're "learning C++". – tadman Nov 02 '12 at 14:26
  • We have been learning C++ and are now learning C (C++ then C as it is closer to Java, which was what they taught us last year). We can use either for this assignment (which I am doing an extension of by making a 2d cellular automata). – Leagsaidh Gordon Nov 02 '12 at 14:30
  • 1
    In C++, swapping can be implemented in one line like so: http://www.cplusplus.com/reference/algorithm/swap/ Still, this might not be what you're looking for, since it "involves a copy construction and two assignment operations", which can be expensive. – Mihai Todor Nov 02 '12 at 14:31
  • The problem is that C++ is not just C with "C++ specific features". Yes, many language features originated with C and the entire C library is included, but writing C++ involves knowing the idioms and best practices of the language. There are many new and better ways to do things that you would do in C and, in fact, many of the fundamentals of the language have evolved and changed over the years, making it incompatible with C. What you're really asking for is C-like C++ but giving an answer like that really doesn't help anybody. However, if you want a C answer *or* a C++ answer, we can do that. – Joseph Mansfield Nov 02 '12 at 14:33
  • I can't see any reason why `bool ** temp = current; current = previous; previous = temp;` wouldn't work just as well. What problem did you have when you tried it? – john Nov 02 '12 at 14:34
  • @MihaiTodor Yeah, I've been avoiding that due to the cost. I've also been avoiding using vectors as I'd like to properly understand how things work at a lower level before using such things (although I have used vectors extensively already). They also have extra functionality that is unnecessary for this project. I think I will go with the method described by tadman. – Leagsaidh Gordon Nov 02 '12 at 14:34
  • @john It doesn't appear to actually swap the arrays. – Leagsaidh Gordon Nov 02 '12 at 14:35
  • @SeanGordon The move semantics from C++11 might alleviate some of the overhead of std::swap, if implemented properly, I think. – Mihai Todor Nov 02 '12 at 14:38
  • @SeanGordon No but it swaps the pointers to them, why isn't that good enough? All your 1d example does is swap the pointers too. – john Nov 02 '12 at 14:38
  • @MihaiTodor I do not have access to C++11 sadly. – Leagsaidh Gordon Nov 02 '12 at 14:42
  • @john Turns out I had a small logic glitch elsewhere that I originally missed which made it appear that the arrays were not actually being swapped. Now I feel stupid. – Leagsaidh Gordon Nov 02 '12 at 15:36

5 Answers5

3

There's no real reason here to bother with an array of arrays. It's a ton more work to maintain and destroy properly, especially as you've avoided using the Standard Library containers that would handle a lot of the memory management for you.

It's usually easier to allocate width * height cells in a single array and reference them like cell[x + width * y] where x is your column, y is your row.

Do keep in mind that in the particular case of this problem what you want is an array of bits and not an array of booleans. C++ does have a special case container for a bitset that is worth using: std::vector<bool>.

Community
  • 1
  • 1
tadman
  • 208,517
  • 23
  • 234
  • 262
  • @MihaiTodor I've been using arrays as it would be easier to then change them to, say, chars and allow the cells to have many different states (for example, an age), but yes, a bitset would be perfect if I'm using a one-dimensional array of bools, and they are already being used in the project. Edit: Actually, bitsets wouldn't work here as they do not allow a dynamic size. – Leagsaidh Gordon Nov 02 '12 at 14:38
  • If you need a dynamic size you're probably approaching this from the wrong angle. A "Game of Life" implementation needs a potentially infinite area or one that wraps around. To deal with a scalable area you should divide the area up into fixed-size regions. Allocating and de-allocating each time is a serious waste of resources. – tadman Nov 02 '12 at 15:52
1

This works:

int arr1[10][10],arr2[10][10]

//Swap 2nd row between arrays
std::swap(arr1[2], arr2[2]);
swapper
  • 11
  • 1
0

If it's C++ use std::vector's and forget about heap allocations, pure arrays, memcpy for them and copy/assignment operators.

Denis Ermolin
  • 5,530
  • 6
  • 27
  • 44
0

Instead of going for your array of arrays, why not use a one-dimensional array of size width*height?

Just access your elements by y*width + x.

Allocate the array as usual with malloc(width*height*sizeof(bool)). This should be sufficient for your problem

Zane
  • 926
  • 8
  • 21
0

While the earlier answers are technically correct, they do not seem to answer your original question. You say "this approach does not work as hoped with the two-dimensional array", but why doesn't the following work?

void () {
    bool ** temp = current;
    current = previous;
    previous = temp;
}

If you don't mind to use c++ features the std::swap functions comes in handy:

std::swap(current, previous);
Yexo
  • 1,865
  • 15
  • 21