1

So this is my program so far:

#include <iostream>
#include <windows.h>
using namespace std;
int colonne;
int ligne;

void initDamier (int damier[ligne][colonne])
{
    for (int i = 0; i < ligne; ++i)
        for (int j = 0; i < colonne; ++j)
            damier[i][j]=0; //0=case vide
}

void afficheDamier (int damier[ligne][colonne])
{
    for (int i = 0; i < ligne; ++i)
    {
        cout<<endl;
        for (int j = 0; j < colonne; ++j)
        {
            cout<<damier[i][j]<<"|";
        }
    }
}

int main()
{
    int a,b;
    cout<<"Entrez le nombre de ligne du damier:"<<endl;
    cin>>a;
    ligne=a;
    cout<<"Entrez le nombre de colonne du damier:"<<endl;
    cin>>b;
    colonne=b;
    int damier[ligne][colonne];
    initDamier(damier);
    afficheDamier(damier);
    return 0;
}

I understand why it's not working. In damier[*][*], * has to be either a const or a fixed number. Can someone tell me how to get around this?

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
D Sam
  • 77
  • 1
  • 2
  • 11
  • 2
    Possible duplicate: [How to create a dynamic array of integers](http://stackoverflow.com/questions/4029870/how-to-create-a-dynamic-array-of-integers) – NathanOliver Apr 19 '16 at 12:44
  • 3
    use `std::vector` or something more appropriate instead of naked c-style arrays – 463035818_is_not_an_ai Apr 19 '16 at 12:44
  • 1
    @NathanOliver your link is to some template question... – 463035818_is_not_an_ai Apr 19 '16 at 12:44
  • @tobi303 Oops. I used the wrong link. Fixed. – NathanOliver Apr 19 '16 at 12:46
  • Possible duplicate: http://stackoverflow.com/q/28308972/2642059 – Jonathan Mee Apr 19 '16 at 13:22
  • See [this anser](http://stackoverflow.com/questions/17259877/1d-or-2d-array-whats-faster/17260533#17260533) on how (and why) to store dense 2d stuff more efficient (as 1d data) with a small sample implementation using `std::vector`. – Pixelchemist Apr 19 '16 at 13:58
  • @Pixelchemist If you feel that's a reasonable solution here, you should type it up as an answer. Personally, I find the approach unnecessarily confusing, and wasteful when run late in a program, because the array must be allocated as a single ginormous block; rather than split into the available holes in memory that are created in normal execution. – Jonathan Mee Apr 19 '16 at 14:36
  • @JonathanMee: It's a comment about what else would probably work well here. You should define "late". I develop HPC software that is often running for weeks and still prefer contiguous allocation for the very reasons I gave in the answer I linked above (as well as the fact that profiling showed a quite remarkable performance gain). Furthermore, usage of the sample implementation I provided is imho less confusing than the handling of plain static arrays. – Pixelchemist Apr 19 '16 at 15:46
  • @Pixelchemist I've had the opposite experience as you, when allocating and working with mega-textures. We found that because there was a lot of dynamic allocations in our program our heap space became sparsely populated. Allocation of a large array caused the OS to have to allocate a bunch more heap pages to our program, which with limited memory was a costly operation. So when we switched to using 2D textures we actually got faster. Because the memory fit into our sparsely populated heap. So by late I mean after the program has a heap with many vacancies. – Jonathan Mee Apr 19 '16 at 16:40

4 Answers4

3

What you are talking about is dynamic memory allocation. As tobi303 says, in C++ you'll probably want to use a vector to handle that.

So the entire first section of your code could be replaced with:

size_t a, b;
cout << "Entrez le nombre de ligne du damier:" << endl;
cin >> a;
cout << "Entrez le nombre de colonne du damier:" << endl;
cin >> b;
vector<vector<int>> damier(a, vector<int>(b, 0));
afficheDamier(damier);

In order to work with a vector you'd also need to modify afficheDamier:

void afficheDamier(vector<vector<int>> damier) {
    for(auto& i : damier){
        cout << endl;
        for(auto& j : i) {
            cout << j << '|';
        }
    }
} 

Live Example

Please note: I've suggested a vector<vector<int>> here, which is probably the simplest approach to getting a toy example working, but in production code, shying away from a vector of vectors would be desirable: What are the Issues with a vector-of-vectors?

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
1

Listen the suggestion of tobi303: use std::vector

#include <vector>
#include <iostream>

void afficheDamier (std::vector<std::vector<int> > const & damier) 
 {
   std::vector<std::vector<int> >::const_iterator  cil;
   std::vector<int>::const_iterator               cic;

   for ( cil = damier.begin() ; cil != damier.end() ; ++cil )
    {
      std::cout << std::endl;

      for ( cic = cil->begin() ; cic != cil->end() ; ++cic )
         std::cout << (*cic) << '|';
    }

   std::cout << std::endl;
 }

int main()
 {
   int ligne, colonne;

   std::cout << "Entrez le nombre de ligne du damier:" << std::endl;
   std::cin >> ligne;
   std::cout << "Entrez le nombre de colonne du damier:" << std::endl;
   std::cin >> colonne;

   std::vector<std::vector<int> > damier(ligne, std::vector<int>(colonne, 0));

   afficheDamier(damier);

   return 0; 
 }

If you are using a C++11 compiler, afficheDamier() can be semplified as follows (as suggested by Jonathan Mee)

void afficheDamier (std::vector<std::vector<int>> const & damier)
 {
   for ( auto const & l : damier )
    {
      std::cout << std::endl;

      for ( auto const & c : l )
         std::cout << c << '|';
    }

   std::cout << std::endl; 
 }
max66
  • 65,235
  • 10
  • 71
  • 111
0

If you want to use arrays and not std::vector, you can use a function template that takes the array by reference:

template<size_t ligne, size_t colonne>
void initDamier (int (&damier)[ligne][colonne])
{
    for (int i = 0; i < ligne; ++i)
        for (int j = 0; j < colonne; ++j) // Note that you had a nasty typo in this line
            damier[i][j]=0;
}

or even

template<size_t ligne, size_t colonne>
void initDamier (int (&damier)[ligne][colonne])
{
    for (auto& x: damier)
        for (auto& y: x)
            y = 0;
}
molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • 1
    Well, yeah, but then you can't choose the dimensions at runtime as in the OP. (Plus, `std::array` is probably easier to use.) – underscore_d Apr 19 '16 at 13:58
-1

Maybe another solution would be:

#include <iostream>
using namespace std;

int colonne;

int ligne;

void initDamier (int **damier, int ligne, int colonne)
{
    for (int i = 0; i < ligne; ++i){
        for (int j = 0; j < colonne; ++j){
            damier[i][j]=0; //0=case vide
        }
    }
}

-

void afficheDamier (int **damier, int ligne, int colonne)
{
    for (int i = 0; i < ligne; ++i)
       {
        cout<<endl;
        for (int j = 0; j < colonne; ++j)
        {
            cout<<damier[i][j]<<"|";
        }
    }
    cout<<endl;
}

-

int main()
{
    int a,b;

    cout<<"Entrez le nombre de ligne du damier:"<<endl;
    cin>>a;
    ligne=a;
    cout<<"Entrez le nombre de colonne du damier:"<<endl;
    cin>>b;
    colonne=b;
    int** damier = new int*[colonne];

    for(int i=0;i<colonne;i++)
        damier[i] = new int[ligne];

    initDamier(damier,ligne, colonne);
    afficheDamier(damier, ligne, colonne);

    for(int i=0;i<colonne;i++)
        delete damier[i];

    delete[] damier;

    return 0;
}
  • 1
    Why allocate manually - and leak memory - when a `vector` already handles all of this for us? – underscore_d Apr 19 '16 at 13:58
  • Yeah you're right you have to do memory handling manually that's why I posted as a"possible solution" – SantyVillagomez Apr 19 '16 at 14:13
  • 1
    Because you return from `main` *without* deleting your memory you are in effect encouraging leaking of memory. This damaging side-effect far out weighs any possible merit your solution may present. Please include deletion, delete your answer, or as @underscore_d suggests, use `vector`. – Jonathan Mee Apr 19 '16 at 14:23
  • I've include deletion,thanks for the comment. However I think it doesn't make sense using `vector` since it's already suggested – SantyVillagomez Apr 19 '16 at 15:27
  • 1
    Sadly your delete is still wrong. `delete damier[i]` should have been `delete[] damier[i]`. Ultimately the problem with this answer is that even if you edit it again to do the deletion properly it will *still* be a poorer solution than using a `vector` :( We're not trying to proposes a bunch of different ways to do this, we're trying to come to a single *best* way to do this. – Jonathan Mee Apr 19 '16 at 16:49
  • 1
    well, if the good solution has already been suggested, then we don't need to add another answer! there's no need to post something else purely for the sake of posting. – underscore_d Apr 19 '16 at 16:50
  • Is up to the person who ask ( or the community) to decide which one fits better for him, not you; the reasons to do so (I think) are again up to the poster too.Anyway thanks for your corrections cause we all are learning – SantyVillagomez Apr 19 '16 at 17:11