1

I was practicing on c++ on some tutorials and I encountered on a tutorial that creates matrices, I wanted something more from it and I modified it, I dont know matrices at all cuz I didnt learn them yet at school but this code below sometimes works sometimes not.
When it doesn't work I usually get: Segmentation fault.
why does this happen ?

before it happened everytime but after i gave a 0 value to variable line and member on the beginning it doesnt happen anymore, but still if I type exc
Line: 10
Member: 9

it gives:

1 1 1 1 1 1 1 1 1

1 2 3 4 5 1 7 8 9
Segmentation fault
and stopes.
Can anyone explain me this ?
thank you !

 #include <iostream>
 #include <iomanip>
 using namespace std;

 int main()
 {
     int line=0,member=0;
     int i,j,matrice[line][member];

     cout << "\nLine: ";
         cin >> line;

     cout << "Member: ";
     cin >> member;

     cout << "\nCreated Matrice: \n" << endl;

         for (i=0;i<line;i++)
         {
             for (j=0;j<member;j++)
             {
                 matrice[i][j]=i*j+1;
                 cout << setw(5) << matrice[i][j];
             }
             cout << "\n\n";
         }
 return 0;
 }
ibanezz
  • 95
  • 2
  • 5

5 Answers5

4
int line=0,member=0;
int i,j,matrice[line][member];

This line shouldn't compile. In standard C++,

  1. arrays of 0 size are not allowed
  2. array sizes must be constant expressions

It appears that your compiler allows these as extensions. In any case when you later input line and member your array size doesn't change. You should define your array after you've input these numbers. But the array must be dynamically allocated (better yet, use vectors)

#include <vector>
//...
int line, member;
cin >> line  >> member;
vector<vector<int> > matrix(line, vector<int>(member));

or if you don't want to use vector for educational purposes, do this:

int line, member;
int ** matrix;
cin >> line  >> member;
matrix = new int*[line];
for(int i = 0; i < line; ++i)
   matrix[i] = new int[member];

Don't forget to free the matrix.

for(int i = 0; i < line; ++i)
   delete [] matrix[i];
delete [] matrix;

I suggest that you should read a good C++ book

HTH

Community
  • 1
  • 1
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • but in my compiler the 'constant line,member;' wont work should I try anything else ? or at least can you help me with some code ? Im still a very beginner... – ibanezz Jul 25 '11 at 11:46
2

The matrice array is initialized with a size of [0][0], which are the values of line and member. Since you override the values with the inputted values, the bounds used in the for loops are invalid.

i.e. You are accessing items out of the array's bounds.

You may want to use new to dynamically create arrays, or just use std::vector which resizes itself.

Also, it is not standard, but if your compiler supports it, you can use variable-length arrays. They behave like regular arrays but are allocated using a runtime-computed value :

int line=0,member=0;
int i,j;

cout << "\nLine: ";
cin >> line;

cout << "Member: ";
cin >> member;

int matrice[line][member];

You should also check for the inputted values, since C++ does not allows zero-size arrays (And it wouldn't make sense in your program anyway.)

slaphappy
  • 6,894
  • 3
  • 34
  • 59
0

You are using dynamic array without allocating memory using malloc or similar. That is in your line int i,j,matrice[line][member]; is not an array with constant size thus memory should be dynamically allocated. Or use a constant matix size as poster above suggested.

morphles
  • 2,424
  • 1
  • 24
  • 26
0

I agree with other comments that using vectors is a much safer way to solve your problem: using arrays directly is definitely error-prone. Of course, if your exercise requires using arrays, then you should use arrays.

Regarding the performance, I have written a small test using g++ on Ubuntu 10.04. Running

g++ --version

I get

g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3

My test program creates a 100x100 matrix and sets each element to some value. It first has a few declarations:

#include <vector>
#include <iostream>
#include "util.h" // Timer utilities.

#define LINE_COUNT (100) // The number of lines.
#define COL_COUNT (100) // The number of columns.

#define REPETITIONS (100000) // Number of repetitions for each test.

using namespace std;

Then I have the test using vectors:

void use_vectors()
{
  int line   = LINE_COUNT;
  int member = COL_COUNT;
  vector<vector<int> > matrix(line, vector<int>(member));

  // Set data.
  for (int i = 0; i < line; i++)
  {
    for (int j = 0; j < member; j++)
    {
      matrix[i][j] = -5;
    }
  }
}

Then I have a function to perform the same test (create matrix and set values) using arrays:

void use_arrays()
{
  int line   = LINE_COUNT;
  int member = COL_COUNT;
  int **matrix; 

  matrix = new int * [line];
  for (int i = 0; i < line; i++)
  {
     matrix[i] = new int[member];
  }

  // Set data.
  for (int i = 0; i < line; i++)
  {
    for (int j = 0; j < member; j++)
    {
      matrix[i][j] = -5;
    }
  }

  for (int i = 0; i < line; ++i)
  {
     delete [] matrix[i];
  }

  delete [] matrix;
}

The main program repeats both tests, and records the time needed for each of them. Here is the main program:

main()
{
  long int es = 0;
  long int eu = 0;
  start_timer();
  for (int i = 0; i < REPETITIONS; i++)
  {
    use_vectors();
  }
  stop_timer();
  es = elapsed_sec();
  eu = elapsed_usec();
  cout << "Vectors needed: " << es << " sec, " << eu << " usec" << endl;

  start_timer();
  for (int i = 0; i < REPETITIONS; i++)
  {
    use_arrays();
  }
  stop_timer();
  es = elapsed_sec();
  eu = elapsed_usec();
  cout << "Arrays needed: " << es << " sec, " << eu << " usec" << endl;
}

The timer functions are based on the library function gettimeofday() (see e.g. http://linux.die.net/man/2/gettimeofday).

The result is the following:

Vectors needed: 24 sec, 624416 usec
Arrays needed:  10 sec, 16970 usec

So it seems that vectors do have some overhead wrt to arrays. Or can I do something to improve the performance of vectors? I checked my benchmark code a few times and it seems to me I got it right.

Anyway, I would by no means advise using arrays just to gain performance unless it really makes a big difference in your application.

Giorgio
  • 5,023
  • 6
  • 41
  • 71
-4

You want to allocate memory dynamically. Then, Use Dynamic allocation like this:

 #include <iostream>
 #include <iomanip>
 using namespace std;

 int main()
 {
     int line=0,member=0;
     int i,j;
     int **matrice; //Define matrice as a 2D array(a Matrix)

     cout << "\nLine: ";
         cin >> line;

     cout << "Member: ";
     cin >> member;

     //start of dynamic allocation
     matrice=new int*[line];
     for (i=0;i<line;i++)
           matrice[i]=new int[member];
     //End of dynamic allocation

     cout << "\nCreated Matrice: \n" << endl;

         for (i=0;i<line;i++)
         {
             for (j=0;j<member;j++)
             {
                 matrice[i][j]=i*j+1;
                 cout << setw(5) << matrice[i][j];
             }
             cout << "\n\n";
         }
 delete[] matrice;  //Releasing allocated memory
 return 0;
 }
Saeed
  • 7,262
  • 14
  • 43
  • 63
  • when I compiled this code it shows me: g++ matrica.cpp -o matrica matrica.cpp: In function ‘int main()’: matrica.cpp:47:27: error: cannot convert ‘int**’ to ‘int*’ in assignment matrica.cpp:49:37: error: invalid conversion from ‘int*’ to ‘int’ matrica.cpp:58:30: error: invalid types ‘int[int]’ for array subscript matrica.cpp:59:49: error: invalid types ‘int[int]’ for array subscript – ibanezz Jul 25 '11 at 11:50
  • You used the first version which was wrong, I edited and corrected it. – Saeed Jul 25 '11 at 11:52
  • 2
    No, you don't want to allocate memory manually. You want to use std::vector or Boost.MultiArray. – Cat Plus Plus Jul 25 '11 at 11:58
  • 1
    In the deallocation part, don't you have to call delete for each line pointer (delete[] matrice[i]) before the final delete[] matrice? – Giorgio Jul 25 '11 at 12:01
  • @Cat Plus Plus: isn't the std::vector solution slower? – Giorgio Jul 25 '11 at 12:02
  • @Giorgio: Slower than what? No, it's not. It's safer — above code is not exception safe, not to mention the author forgot to delete inner arrays, creating a leak. There is no reason to not use safe containers. – Cat Plus Plus Jul 25 '11 at 12:04
  • @Cat Plus Plus: No doubt that it is safer to use a vector. I was just wondering whether using vectors is slower than using a plain arrays. I do not know how standard vectors are implemented internally. – Giorgio Jul 25 '11 at 12:11
  • @cat++- I just offered this manually allocating cause it was a simple little program which I think doesn't need to use that, and also to learn how to allocate dynamic arrays. and vectors will be slower and less efficient. – Saeed Jul 25 '11 at 12:11
  • @ Giorgio- I think no need to delete like that, I think the command "delete[]" will do that itself, but not sure. – Saeed Jul 25 '11 at 12:14
  • @saeed: I think the delete[] you wrote will only deallocate what you allocated with matrice = new int*[line]. – Giorgio Jul 25 '11 at 12:15
  • All the other arrays that you have allocated with matrice[i]=new int[member]; are not deallocated automatically. – Giorgio Jul 25 '11 at 12:17
  • @saeed: Basically, you didn't get anything right, so I guess I'll just downvote this answer as harmful to the OP. – Cat Plus Plus Jul 25 '11 at 12:25
  • 4
    @saeed: vectors are absolutely as efficient as `new[]`. If you think they aren't, then you need to learn more C++. Even if vector was slower, having the proper memory guarantees is absolutely essential, especially when helping other people, and doing `new[]` because it might be faster is inexcusable in sample code. – Puppy Jul 25 '11 at 12:31
  • 1
    @Giorgio: no, it is not slower. The standard library containers are, thanks to the magic of templates and generic programming, implemented to be *exactly* as efficient as hand-coded alternatives. For vectors in particular, there is literally zero overhead when compared to a dynamically allocated array. – jalf Jul 25 '11 at 12:31
  • It's easy to write fast programs that output garbage. – R. Martinho Fernandes Jul 25 '11 at 12:44
  • I'm sure that vectors perform slower than dynamic arrays, and thats because of double sizing it on overflows (and half sizing on emptiness)(that's not exactly how vectors work, but similar), but you all are right and I think this very little gain in performance dose not worth to deal with garbages. – Saeed Jul 26 '11 at 05:39