How does this not return a 2D Array?

Hi, a test case for my code is stored at: http://codepad.org/YWvbEQ6X,

My boss says that my code does not actually return a pointer to a 2D Array as I've stated in my documentation of the function

char ** split(char* tokenizeMe, const char* delim, int &numOfItems)

Can someone please explain to me why he says this?
Cause it looks like a pointer to a 2D array of characters.

Thank you,
leeand00
You are both correct. :-]

If you want to be really technical, you are returning a pointer to a pointer to a char. C++ allows you to treat pointers as arrays, because:
a[ n ]
is really shorthand for
*(a + n)
Therefore, it follows that a pointer to data can be treated as an array of data.

This leads to an interesting feature of the language: a 2D array can be physically represented in two different ways.

But before we get that far, remember that in C there really is no such thing as a multidimensional array... only the appearance of one. All arrays are actually linear.

The first representation of a 2D array is just some funky indexing of a linear array.
1
2
3
4
5
6
7
8
9
10
11
// This creates a ONE-dimensional array of integers
// that are indexed as if it were a TWO-dimensional array.
int a[ 10 ][ 20 ];

// But we can still treat it as a one-dimensional array.
int* b = a;

// Each of the following statements do exactly the same thing
a[ 5 ][ 7 ] = 42;
*(b + (5 * 20) + 7) = 42;
*(b + 107) = 42;

In fact, the first statement is, again, a convenience for us programmers. The compiler will convert it into the second if any of the indices are variable, or the third if all indices are constant (as they are in the example).

The second representation capitalizes on the "pointer is an array" feature of the language in a different way, and adds a new power to arrays that the first method lacks: variably-dimensioned subscripts. For example:
1
2
3
4
5
6
7
8
const char* names[ 5 ] =
  {
  "Anne",
  "Courtney",
  "Nuala",
  "Seanaed",
  "Tera"
  };

In this case, the array names is really an array of const char* (like it says it is), but what if I had written the declaration as:
const char** names =
It is technically correct. The compiler will prevent it in order to keep the programmer from shooting himself in the foot, but you can use the construct in a function's argument list and pass names to the function -- where the compiler forgets all dimensional information about the original array. (That's why we pass the size of an array to functions also... since we can't rely on the compiler to give us information about the original array from a function.)

Using the array is exactly the same: to access the third letter of the second name we write:
cout << names[ 1 ][ 2 ] << endl;
Remembering that we just used some fancy syntax magic to do something simpler with pointers, we can rewrite it as:
cout << *(*(names + 1) + 2) << endl;

In other words, we first dereference the outer dimension
char* inner_char_pointer = *(names + 1);
to find the inner array's char pointer, then we dereference that pointer to get the character desired.
char c = *(inner_char_pointer + 2);

So, to keep your boss happy, you might want to be explicit about the way the 2D array is stored:
1
2
3
4
returns
  NULL on failure.
  Else a pointer to an array of (char*). Each sub-array of characters represents ...
  All data is allocated on the heap using malloc().


Hope this helps.
Last edited on
Topic archived. No new replies allowed.