Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to secure member variables used in member functions?

45 views
Skip to first unread message

JiiPee

unread,
Sep 25, 2015, 9:25:48 AM9/25/15
to
Say I have a class with some pointer which points to a data if set and
to null if not set:

class MyClass
{
void setData(int* data) { m_data = data; }
void useData();
private:
int* m_data{null_ptr};
};

Lets say we have to set the value where its pointing to: *m_data.
Now, in useData we have to check whether m_data is null to be able to
use it:

void MyClass::useData()
{
if(!m_data)
return;
// m_data is set, so can safely be used
*m_data = 2015;
}

Now (and I get this a lot), what is the best practise to secure m_data?
because lets say we have this checking:
if(!m_data)
return;
in 20 different places, there is a possibility I forget to check it and
program crashes. I could created a function:

void MyClass::safelySetData(int val)
{
if(!m_data)
return;
*m_data = val;
}

but this does not stop other member functions getting access to m_data
and use it with null pointer (crashing).

I was thinking creating a new class and putting it to a private member:

class Data
{
void setDataPointTo(int* data) { m_data = data; }
void reallySafelySetData(int val) { if(m_data) *m_data = val; }
private:
int* m_data{null_ptr};
};

and having Data object in MyClass:

class MyClass
{
private:
Data m_data{null_ptr};
};

Now this would do the job, but its a bit difficult way to do a simple
single variable thing. Is there any other, more simple, way to secure
m_data so that functions cannot touch it? How do you do this? Or you
just check the null-case and hope that no function is missusing the pointer?

Best way would be if I could somehow tell that only safelySetData can
modify m_data pointer. But that is not possible in C++ I think?


Paavo Helde

unread,
Sep 25, 2015, 10:34:31 AM9/25/15
to
JiiPee <n...@notvalid.com> wrote in news:YWbNx.1$5b...@fx04.am4:

> Say I have a class with some pointer which points to a data if set and
> to null if not set:
>
> class MyClass
> {
> void setData(int* data) { m_data = data; }
> void useData();
> private:
> int* m_data{null_ptr};
> };
>
> Lets say we have to set the value where its pointing to: *m_data.
> Now, in useData we have to check whether m_data is null to be able to
> use it:
>
> void MyClass::useData()
> {
> if(!m_data)
> return;
> // m_data is set, so can safely be used
> *m_data = 2015;
> }
>
> Now (and I get this a lot), what is the best practise to secure
> m_data? because lets say we have this checking:
> if(!m_data)
> return;
> in 20 different places, there is a possibility I forget to check it
> and program crashes.

The best practice is to get rid of the pointer. If the data needs to
remain a separate object by some reason, then one way is to use a
reference instead of the pointer and initialize it in the MyClass
constructor. Reference cannot be null, so problem solved.

> I was thinking creating a new class and putting it to a private
> member:
>
> class Data
> {
> void setDataPointTo(int* data) { m_data = data; }
> void reallySafelySetData(int val) { if(m_data) *m_data = val; }
> private:
> int* m_data{null_ptr};
> };
>

Yes, that's the way to go if there is no way to avoid the pointer. Such
simple wrappers are easily optimized away by the compiler so there is no
difference performance-wise.

JiiPee

unread,
Sep 25, 2015, 11:27:17 AM9/25/15
to
On 25/09/2015 15:34, Paavo Helde wrote:
> JiiPee <n...@notvalid.com> wrote in news:YWbNx.1$5b...@fx04.am4:
>
> The best practice is to get rid of the pointer.

In my situation I cannot bce a thread-function returns a pointer...

>> I was thinking creating a new class and putting it to a private
>> member:
>>
>> class Data
>> {
>> void setDataPointTo(int* data) { m_data = data; }
>> void reallySafelySetData(int val) { if(m_data) *m_data = val; }
>> private:
>> int* m_data{null_ptr};
>> };
>>
> Yes, that's the way to go if there is no way to avoid the pointer. Such
> simple wrappers are easily optimized away by the compiler so there is no
> difference performance-wise.

ok. The question is obviously that do we need to do this wrapper or not?
is it necessary? I kind of like it makes sure nobody can use
null-pointer... but it takes more work, and sometimes lazy.. :)


mark

unread,
Sep 25, 2015, 11:30:09 AM9/25/15
to
On 2015-09-25 16:34, Paavo Helde wrote:
> The best practice is to get rid of the pointer. If the data needs to
> remain a separate object by some reason, then one way is to use a
> reference instead of the pointer and initialize it in the MyClass
> constructor. Reference cannot be null, so problem solved.

With C++11, you have reference_wrapper:
http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper

This can be quite useful, if you want to use a reference but need to be
able to rebind it. They can also be stuffed into standard containers.

Paavo Helde

unread,
Sep 25, 2015, 11:48:11 AM9/25/15
to
JiiPee <n...@notvalid.com> wrote in news:%IdNx.408$8%3....@fx31.am4:
You already almost completed it, and changing 20 code locations calling
it is not so hard. I bet writing those 20 tedious checks was more work,
more boring, and more error-prone.

Cheers
Paavo




JiiPee

unread,
Sep 25, 2015, 1:55:25 PM9/25/15
to
On 25/09/2015 16:47, Paavo Helde wrote:
> JiiPee <n...@notvalid.com> wrote in news:%IdNx.408$8%3....@fx31.am4:
>
>> is it necessary? I kind of like it makes sure nobody can use
>> null-pointer... but it takes more work, and sometimes lazy.. :)
> You already almost completed it, and changing 20 code locations calling
> it is not so hard. I bet writing those 20 tedious checks was more work,
> more boring, and more error-prone.
>
>

yes I kind of agree ...

JiiPee

unread,
Sep 25, 2015, 1:57:14 PM9/25/15
to
On 25/09/2015 16:27, Stefan Ram wrote:
> JiiPee <n...@notvalid.com> writes:
>> Now this would do the job, but its a bit difficult way to do a simple
>> single variable thing.
> I'd do it this way too. It is not difficult.
>

ok, good to know people agree with it. So I can start using it then...

I just felt the class for one variable only is a bit too "heavy", but
thats the way to do it.

Maybe the language can someday have a security key for this. It might be
a good new feature for C++ :)

Paavo Helde

unread,
Sep 25, 2015, 2:37:23 PM9/25/15
to
JiiPee <n...@notvalid.com> wrote in news:MVfNx.1028$JB7...@fx42.am4:

> On 25/09/2015 16:27, Stefan Ram wrote:
>> JiiPee <n...@notvalid.com> writes:
>>> Now this would do the job, but its a bit difficult way to do a simple
>>> single variable thing.
>> I'd do it this way too. It is not difficult.
>>
>
> ok, good to know people agree with it. So I can start using it then...
>
> I just felt the class for one variable only is a bit too "heavy", but
> thats the way to do it.

There are many useful classes with no data members at all in C++.

The general idea is that a single class should have a single
"responsibility". Managing the null-or-not-null data pointer seems a
pretty clear responsibility.

> Maybe the language can someday have a security key for this. It might
be
> a good new feature for C++ :)

Your probably mean the standard library, not the C++ core language.
Anyway, it is not so simple because it is not straightforward what should
happen if the pointer is not in the expected state in either of the
get/set part. In my own code I would probably put asserts there, instead
of just ignoring any inconsistencies (as your design appears to
prescribe).

Cheers
Paavo

Alf P. Steinbach

unread,
Sep 25, 2015, 3:09:32 PM9/25/15
to
This general idea of encapsulation is indeed the way to go, provided
that it's really necessary to store and access values in a location
specified and occasionally changed by client code.


> and having Data object in MyClass:
>
> class MyClass
> {
> private:
> Data m_data{null_ptr};
> };
>
> Now this would do the job, but its a bit difficult way to do a simple
> single variable thing. Is there any other, more simple, way to secure
> m_data so that functions cannot touch it? How do you do this? Or you
> just check the null-case and hope that no function is missusing the
> pointer?
>
> Best way would be if I could somehow tell that only safelySetData can
> modify m_data pointer. But that is not possible in C++ I think?

AFAIK only by way of inheriting that from a class like your Data. ;-)


Cheers & hth.,

- Alf

JiiPee

unread,
Sep 25, 2015, 3:40:39 PM9/25/15
to
On 25/09/2015 19:37, Paavo Helde wrote:
> get/set part. In my own code I would probably put asserts there,
> instead of just ignoring any inconsistencies (as your design appears
> to prescribe).

yes, debug time asserts are very good there for sure. There is nothing
to lose to do them neither.

Jorgen Grahn

unread,
Sep 26, 2015, 2:15:54 AM9/26/15
to
On Fri, 2015-09-25, Paavo Helde wrote:
> JiiPee <n...@notvalid.com> wrote in news:MVfNx.1028$JB7...@fx42.am4:
>
>> On 25/09/2015 16:27, Stefan Ram wrote:
>>> JiiPee <n...@notvalid.com> writes:
>>>> Now this would do the job, but its a bit difficult way to do a simple
>>>> single variable thing.
>>> I'd do it this way too. It is not difficult.
>>>
>>
>> ok, good to know people agree with it. So I can start using it then...
>>
>> I just felt the class for one variable only is a bit too "heavy", but
>> thats the way to do it.
>
> There are many useful classes with no data members at all in C++.
>
> The general idea is that a single class should have a single
> "responsibility". Managing the null-or-not-null data pointer seems a
> pretty clear responsibility.

Another common example of a class with not a lot of data in it is when
you find a need for a type, and discover that its internal state can
be represented as (for example) just an integer. Same internal state
as an int ... but a very different (and much smaller) set of operations.

One of the best habits I picked up over the years is to /resist/ the
temptation to "just use an int" or a typedef, and to write that tiny
class. My code becomes a lot clearer and safer.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
0 new messages