tags:

views:

1433

answers:

7

Hi,

I have a function which takes a triple pointer as an argument:

int somefunction(tchar ***returnErrors);

Does anyone know how to allocate the memory for the returnErrors parameter?

Thanks!

Niko

A: 

The triple pointer does not make any sense if you don't already have a construct of that type. I would rather recommend using a class - or at least a standard container. But if you must know, it's as simple as

tchar ***pointer = (tchar***) malloc(sizeof(tchar**) * amount);
soulmerge
I think you have one * missing. It should instead be (tchar***) malloc(... .
Comptrol
Oh, you're right, thanks
soulmerge
Just one more thing. Remove the cast and ensure that stdlib.h is included.
robUK
+1  A: 

It depends on what "somefunction" is expecting. You have to investigate on this !

It may be expecting a pointer to a fixed-size array of dimension 2, or a regular array of dimension 3, or ???

In the cases i mentionned, code could look like

tchar errors[SIZE1][SIZE2];
somefunction( &errors );

or

tchar errors[SIZE1][SIZE2][SIZE3];
somefunction( errors );
Benoît
Or probably dozens of other possibilities. It is completely impossible to know what is expected without documentation (or source) for `somefunction`.
Sol
Right. But I figured simply answering "It depends" would not be of much use ! :-)
Benoît
+2  A: 

At a guess . . .

You can think of returnErrors as a pointer to an array of strings.

  1. The first * imples pointer to array of tchar (or a single string of tchars)
  2. The second * imples a pointer to an array of strings.
  3. The last * is so you can change returnErrors and pass back the new memory.

To delare memory for this (silly example, allocating memory inside SomeFunction)

tchar ** errors;
// Oops it appears I need to pass back two error strings (+ 1 for null on end, so we know there are no more - thanks tlholaday)
errors = malloc(sizeof(tchar*) * 3);

// the first string has length 20 (+ 1 for null terminator)
errors[0] = malloc(sizeof(tchar) * 21);

// the second string has length 30 (+ 1 for null terminator)
errors[1] = malloc(sizeof(tchar) * 31);

// ensure the last is null
errors[2] = 0;

*returnErrors = errors;

NB: The calling function needs to know that SomeFunction has allocated memory and needs to free it.

Binary Worrier
You might want errors = malloc(sizeof(tchar*) * 3) so you can stick a null terminator in errors[2] to indicate "no more strings."
Thomas L Holaday
+2  A: 

Are you implementing somefunction or calling somefunction?

If you are calling somefunction, it is likely that somefunction will be allocating the memory, so all you need to do is pass it a safe place to scribble and clean up afterwards.

tchar **theErrors = 0; // a vector of tchar vectors.
somefunction(&theErrors); 
if (theErrors) {
  // use the error values
  // free the memory somehow - this is for a null-terminated convention
      tchar **victim = theErrors;
      while (*victim) delete[](*victim++);
      delete[] theErrors;
}

Note: I'm using 0 and delete[] instead of NULL and free because the tag says c++.

Thomas L Holaday
My guess is that the function returns the number of NULL-terminated strings allocated into theErrors array.
Eclipse
I imagined the function would return an HRESULT, with S_OK, S_FALSE, E_FAIL, E_NOT_IMPLEMENTED etc.This problem reminds me why I prefer ... somefunction( std::vector<std::string> >
Thomas L Holaday
A: 

There are two use cases for a funciton like your someFunction() that I would use.

For initialization:

{
    tchar **returnErrors;

    initErrors(tchar &returnErrors);
    /* now returnErrors has a place in memory*/
}

int initErrors(tchar ***returnErrors)
{
    *returnErrors = malloc(sizeof(tchar *) * SIZE1)

     for (i = 0; i < NUM_ELEMENTS; i++)
         (*returnErrors)[i] = malloc(sizeof(tchar) * SIZE2);

    /*add checks for malloc failures*/
}

Array passing to a function:

{
    returnErrors[SIZE1][SIZE2][SIZE3];

    someFunciton(returnErrors);
}

int someFunciton(tchar ***returnErrors)
{
    /*assuming that this is a valid index*/
    tchar x = returnErrors[1][1][1]; 
    /*return errors is used as a triple array*/
}
lillq
+1  A: 

Does anyone know how to allocate the memory for the returnErrors parameter?

The question is too generic and cannot be answered in the general case. Following is just an example of a possible code snippet that calls it.

tchar foo;
tchar * p_foo = &foo;
tchar ** pp_foo = &p_foo;
tchar *** ppp_foo = &pp_foo;
somefunction(ppp_foo);

Just a comment: I would consider your function signature unsafe and thus a code smell even if it had one star less.

Also, note:

  • A pointer is never an array. It is a variable which contains the value of a memory address, or NULL.
  • The address that a pointer contains doesn't always correspond to the starting address of an array. int ** p is not always refering to the starting address of an int[][].
  • A pointer whose value contains the starting address of an array is not the best way to pass this array as a function parameter. Instead, a reference to the array type can be used.
  • An array is usually not the best way to contain a set of related values in C++. std::vector and other STL containers should be considered. (However your question has two languages, C and C++, as tags; of course this only applies to the latter possibility. Why the two tags?)
Daniel Daranas
A: 

I'd tend agree with tlholaday's guess, with the modification that the function likely returns the number of errors it allocates.

tchar **theErrors = 0; // a vector of tchar vectors.
int nErrors = somefunction(&theErrors); 
if (nErrors > 0) {
     for (int i = 0; i < nErrors; ++i)
     {
         printf(theErrors[i]);
         free(theErrors[i]);
     }
     free(theErrors);
}

Note that whether you use free or delete[] will depend on how the memory was allocated in the first place.

Eclipse