tags:

views:

227

answers:

5

I have a segmentationfault at the line : cout << b[0][0];

Someone can tell me what I should do to fix my code?

#include <iostream>
using namespace std;

int** gettab(int tab[][2]){
   return (int**)tab;
}

int main() {
   int a[4][2] = {{0, 0}, {1, 0}, {2, 0}, {2, 1}};
   int ** b = gettab(a);
   cout <<  b[0][0];
   return 0;
}
+5  A: 

A 2-dimensional array is not the same thing as an array of pointers, which is how int** is interpreted. Change the return type of gettab.

int* gettab(int tab[][2]){
   return &tab[0][0];
}

int main() {
  int a[4][2] = {{0, 0}, {1, 0}, {2, 0}, {2, 1}};
  int* b = gettab(a);
  cout << b[0]; // b[row_index * num_cols + col_index]
  cout << b[1 * 2 + 0]; // the 1 from {1, 0}
}

Or:

int (*gettab(int tab[][2]))[2] {
  return tab;
}
// or:
template<class T> struct identity { typedef T type; };
identity<int(*)[2]>::type gettab(int tab[][2]) {
  return tab;
}

int main() {
  int a[4][2] = {{0, 0}, {1, 0}, {2, 0}, {2, 1}};
  int (*b)[2] = gettab(a);
  cout << b[0][0];
}
Roger Pate
If you're going to downvote, leave a comment to say why.
Roger Pate
this line : int (*)[2] gettab2(int tab[][2]){doesn't compile. I have the error : main.cpp|14|error: expected unqualified-id before ‘)’ token|main.cpp|14|error: expected initializer before ‘gettab2’|
Should be int (* gettab(int tab[][2])) [2]I recommend not returning arrays though :)
DanDan
@Roger The downvote wasn't from me, but your second solution looks strange to me and doesn't compile with my compiler (VS 2005), does this work for you?
Andreas Brinck
My fault on the syntax, fixed and provided an easier to read alternative. (A typedef of `int(*)[2]` works too.)
Roger Pate
The downvote was actually before I had the code sample in there, which I edited in within the first 5 minutes.
Roger Pate
int (*gettab(int tab[][2]))[2] { return tab;}is working but wow, it looks horrible :)Tomorrow I'll try to use Boost instead. Thank you very much for your help
unknown: I agree that there's probably a better solution to what you're really doing, but since you've not said what you're really doing all I can do is fix the example you put in the question. :)
Roger Pate
+1  A: 

Your seg fault us because you pass in an "int*" effectively. A 2D array is not a double pointer ...

You are best off using a pointer that is "x*y" in size and addressing it without the 2 dimensions ... the code will end up the same anyway as the compiler will just generate the same code you would have to write more explicitly anyway :)

Goz
+3  A: 

Being c++, rather than c, there are much better ways of handling arrays of all sorts, and passing them around.

Autopulated
+1 I wish that everyone knew that :)
Kornel Kisielewicz
another good link: http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.11 " Why shouldn't my Matrix class's interface look like an array-of-array?"
danio
@danio but my matrix class's interface does look like that, oh no D:
Autopulated
A: 

a 2 diminsional array isn't the same thing as an array of pointers. a 2 dimensional array is just a pointer to a hunk of memory that you have told the compiler to let you access as a 2 dimensional array

int* gettab(int tab[][2]) {   
   return (int*)tab;
}

int main() {   
   int a[4][2] = {{0, 0}, {1, 0}, {2, 0}, {2, 1}};   
   int* b = gettab(a);   
   cout <<  b[0 + 2*0];   
   return 0;
}

will do what you want. But I wonder if you really need to be trying to return a 2 dimensional array from a function in the first place. Perhaps a less made-up example if what you are trying to do would be helpful?

edit: fixed missing 2 in the calculation [0 + (sizeof(int)2)*0]. edit again: well that was dumb. the multiplication of the column size of 2 by the size of an int is automatic in this case. sizeof(int) removed.

John Knoeller
What exactly is `sizeof(int)` doing in `b[0 + sizeof(int)*0]`?
avakar
just stupid mistake.
John Knoeller
+2  A: 

The type of tab without square brackets is not actually int **. It is actually int (*)[2]. When you apply two [] operators to the resulting pointer, you end up dereferencing the first value in your array, 0, as a NULL pointer. Try this instead:

#include <iostream>
using namespace std;

typedef int (*foo)[2];

foo gettab(int tab[][2]){
   return tab;
}

int main() {
   int a[4][2] = {{0, 0}, {1, 0}, {2, 0}, {2, 1}};
   foo b = gettab(a);
   cout <<  b[0][0];
   return 0;
}
Aaron Klotz