2

I have a function that have a char* as parameter to receive some informations from inside the function. (int foo(char* param1))

How can I be sure that this parameter have the enough allocated space to receive all the information I need to put in? I can be sure if it is, or not, a valid pointer, but I haven't found a way to be sure about the size/length allocated to the parameter.

I can't change the function (can't add another parameter with the size).

jleahy
  • 16,149
  • 6
  • 47
  • 66
Luiz Antonio
  • 223
  • 1
  • 2
  • 6
  • 4
    You can try writing stuff into `param1` until something crashes. This gives you an upper bound on the allocated place ;) – Lior Aug 28 '12 at 18:54
  • Why are you using C strings in a C++ program ? – Paul R Aug 28 '12 at 19:02
  • @PaulR maybe for a C interface-compatibility... Or because he's Linus Torvalds. –  Aug 28 '12 at 19:03
  • @PaulR it is for C compatibility. – Luiz Antonio Aug 28 '12 at 19:07
  • 1
    possible duplicate of [passing char buffer to functions and getting the size of the buffer](http://stackoverflow.com/questions/609267/passing-char-buffer-to-functions-and-getting-the-size-of-the-buffer) – Bo Persson Aug 28 '12 at 19:30

4 Answers4

6

AFIAK, C++ does not have any facility to verify the amount of space allocated to a pointer. If the input points to a NULL-terminated array of chracters (i.e. a c-string), then you can use strlen(). Typically these kinds of functions in C and C++ must be well-documented as to what is expected from the parameters. The function is typically implemented assuming the the caller honors the documented contract.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
5

If I have understood the question correctly, there is no way for you to ascertain the size of valid memory associated with the pointer. If this was pointing to an array of data, the usual way to pass a size parameter but if you do not have that option, you do not know what you will be accessing

mathematician1975
  • 21,161
  • 6
  • 59
  • 101
4

Easy answer: you can't.

Little more complicated C-style answer: if that array of chars has a terminating NUL (0) byte, you can use strlen().

OS-specific answer: if the memory for the array was obtained using malloc(), you can use malloc_size() and malloc_usable_size() at least on OS X and Linux, respectively. On windows, for applications that use the Microsoft C Runtime, there's the _msize() function.

  • If the memory was obtained like this "char foo[10];" Can I use anything else? – Luiz Antonio Aug 28 '12 at 19:06
  • 1
    @LuizAntonio yes, for auto arrays, `sizeof(foo)` gives the size of the array in bytes. However, you can't do it *from inside* the function, because for the function, the array is just a pointer; you have to pass this size parameter as a separate argument. –  Aug 28 '12 at 19:08
  • 1
    In other words, "sizeof(foo)" only works for code that has visibility to "char foo[10]". So usually you *cannot* use this technique inside of a function... – paulsm4 Aug 28 '12 at 19:24
  • @paulsm4 exactly. But this doesn't appear to be a serious problem. –  Aug 28 '12 at 19:31
1

You can't be sure. Not really. The only practical check you can do for pointer validity is to check if it is not NULL.

As far as knowing size of the the buffer param1 points to, the only thing that comes to mind is this stupid hack. Before callting function, put the size of the buffer in at the beginning of the buffer that param1 points to. Then, copy your data into the buffer, overwriting the size when you are done with checks.

Like this:

*(unsigned int*)param1 = buf_size;
foo(param1);

int foo(char* param1)
{  
    if (0 == param1)
    {
        // fail
    }

    unsigned int buf_size = *(unsigned int*)param1;

    if (buf_size < whateverlimit)
    {
        // fail
    }

    // copy data into the buffer
}

I have not compiled this code so it might need some corrections.

Mihai Iorga
  • 39,330
  • 16
  • 106
  • 107
Igor
  • 11
  • 1
  • OMG, this is a clever hack, indeed. However, this code should be definitely improved if you don't want to invoke UB. –  Aug 28 '12 at 19:32