Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   access violation on static nonst (http://www.velocityreviews.com/forums/t957465-access-violation-on-static-nonst.html)

woyt.a 02-09-2013 09:22 PM

access violation on static nonst
 
Hi,

following code:

int main()
{
const size_t val0 = 0;
static const size_t val1 = 0;

// works ok
size_t* pVal0 = const_cast<size_t*>(&val0);
*pVal0 = 5;

// causes access violation errof on runtime
size_t* pVal1 = const_cast<size_t*>(&val1);
*pVal1 = 7;

return 0;
}

can change value of val0 const variable but invokes segmentation fault for val1.
This is known issue, as val1 is put in the read-only memory page.

My question is:
1. is there any way to change static cont variable value?
2. is there any way to prevent compller to put that variable in read-only memory?

Regards,
woyt.a

Ike Naar 02-09-2013 10:22 PM

Re: access violation on static nonst
 
On 2013-02-09, woyt.a <itf.woyt@gmail.com> wrote:
> Hi,
>
> following code:
>
> int main()
> {
> const size_t val0 = 0;
> static const size_t val1 = 0;
>
> // works ok
> size_t* pVal0 = const_cast<size_t*>(&val0);
> *pVal0 = 5;
>
> // causes access violation errof on runtime
> size_t* pVal1 = const_cast<size_t*>(&val1);
> *pVal1 = 7;
>
> return 0;
> }
>
> can change value of val0 const variable but invokes segmentation fault for val1.
> This is known issue, as val1 is put in the read-only memory page.
>
> My question is:
> 1. is there any way to change static cont variable value?
> 2. is there any way to prevent compller to put that variable in read-only memory?


If you want to change the variable, why declare it 'const'
in the first place?

Dombo 02-09-2013 10:30 PM

Re: access violation on static nonst
 
Op 09-Feb-13 22:22, woyt.a schreef:
> Hi,
>
> following code:
>
> int main()
> {
> const size_t val0 = 0;
> static const size_t val1 = 0;
>
> // works ok
> size_t* pVal0 = const_cast<size_t*>(&val0);
> *pVal0 = 5;
>
> // causes access violation errof on runtime
> size_t* pVal1 = const_cast<size_t*>(&val1);
> *pVal1 = 7;
>
> return 0;
> }
>
> can change value of val0 const variable but invokes segmentation fault for val1.
> This is known issue, as val1 is put in the read-only memory page.
>
> My question is:
> 1. is there any way to change static cont variable value?


My question is: why declare a 'variable' const if you intend to change it?

> 2. is there any way to prevent compller to put that variable in read-only memory?


Not with just standard C++.

Trying to change a variable by const_cast<> that really is const is
undefined behavior as far as the C++ standard is concerned. In other
words, anything may happen: it may (seem to) work, it may result in a
segmentation fault, it may mail your extensive collection of porn to
your mom or even may wipe out your hard disk; all are acceptable as far
as the C++ standard is concerned.


woyt.a 02-09-2013 11:15 PM

Re: access violation on static nonst
 
ok this is an example of only to make my real problem readable. That why I want to change const variable. But this is outline of real problem:

header:
class clsElement
{
private:
int m_val;
public:
clsElement(int val) : m_val(val) {}
};

class clsTest
{
public:
clsTest();
virtual ~clsTest();
protected:
private:
// this is critical not to use array size here
static clsElement m_array[];
};

cpp;
#include <stdlib.h>
#include <Test.h>

clsElement clsTest::m_array[] = {clsElement(0), clsElement(1), clsElement(2) };

// this generates error as clsTest::m_array is private.
const size_t count_elements = _countof(clsTest::m_array);

clsTest::clsTest() {}
clsTest::~clsTest() {}

so my idea was to initialize this with zero first
const size_t count_elements = 0;

than wanted to force count_elements to get array elements count in the constructor:

clsTest::clsTest()
{
size_t* pcount_elems = const_cast<size_t*>(&count_elems);
*pcount_elems = _countof(m_array);
}

but it causes access violation.

Regards,
woyt.a


Balog Pal 02-09-2013 11:16 PM

Re: access violation on static nonst
 
On 2/9/2013 10:22 PM, woyt.a wrote:
> My question is:
> 1. is there any way to change static cont variable value?


Not in standard C++. the rule is simple: if an object is defined as
const, modification of it by any possible means is undefined behavior.
(a particular implementation may define it for you, but hardly any will
bother).

> 2. is there any way to prevent compller to put that variable in read-only memory?


Sure: don't make it const. I wonder why you do it, if you intend to
change it right ahead.

The practical way is to postpone initialization of the const until the
first use, and use proper init expression to set the desired value, that
is stay so for the rest.



Victor Bazarov 02-09-2013 11:38 PM

Re: access violation on static nonst
 
On 2/9/2013 6:15 PM, woyt.a wrote:
> ok this is an example of only to make my real problem readable. That why I want to change const variable. But this is outline of real problem:
> [..example involving const_cast and changing a const object]
>
> but it causes access violation.


"Doctor, when I do this, it hurts."
"Well, don't do that."

V
--
I do not respond to top-posted replies, please don't ask

Marcel Müller 02-10-2013 05:27 PM

Re: access violation on static nonst
 
On 10.02.13 00.15, woyt.a wrote:
> than wanted to force count_elements to get array elements count in the constructor:
>
> clsTest::clsTest()
> {
> size_t* pcount_elems = const_cast<size_t*>(&count_elems);
> *pcount_elems = _countof(m_array);
> }


Many things go wrong here. First of all, you have /one/ instance of
count_elems, but you try to override it's value on each constructor
invocation.

> but it causes access violation.


Of course, you tried to modify the executables memory image. Static POD
constants are usually part of the executable.


> // this generates error as clsTest::m_array is private.
> const size_t count_elements = _countof(clsTest::m_array);


In fact, it seems that you are looking for something else.
make count_elements a public member of clsTest and you will no longer
get an error that clsTest::m_array is private at the initialization.


Marcel

woyt.a 02-10-2013 07:47 PM

Re: access violation on static nonst
 
> > clsTest::clsTest()
> > {
> > size_t* pcount_elems = const_cast<size_t*>(&count_elems);
> > *pcount_elems = _countof(m_array);
> > }

>
> Many things go wrong here. First of all, you have /one/ instance of
> count_elems, but you try to override it's value on each constructor
> invocation.


I agree this is not elegant, just searching for solution. But in fact m_array is one instance only too, so setting it's size in count elemnts everytime clsTest object is created should not break anything. Worse side of that is, that it is not set at all if no clsTest object is created.

> In fact, it seems that you are looking for something else.
> make count_elements a public member of clsTest and you will no longer
> get an error that clsTest::m_array is private at the initialization.


My first attemption was to make private field in clsTest:

private:
static const size_t m_count_elements;

I cannot initiazlie it in the header:

private:
static const size_t m_count_elements = _countof(m_array);

because there is no size of m_array specified (wat it important for the problem) in the clsTest definition. m_count_elements does not need to be public but it is important to be static (this is value for one m_array only) andexpectation is to be const.
But when trying to initialize it just after m_array is initialized in cpp file
const size_t clsTest::m_count_elements = _countof(clsTest::m_array);
get error that clsTest::m_array is not accessible. I think the issue here is _counof macro, that is defined in stdblib probably in VC++ only. Am I correct?

Regards,
woyt.a

Ike Naar 02-10-2013 10:37 PM

Re: access violation on static nonst
 
On 2013-02-10, woyt.a <itf.woyt@gmail.com> wrote:
>> > clsTest::clsTest()
>> > {
>> > size_t* pcount_elems = const_cast<size_t*>(&count_elems);
>> > *pcount_elems = _countof(m_array);
>> > }

>>
>> Many things go wrong here. First of all, you have /one/ instance of
>> count_elems, but you try to override it's value on each constructor
>> invocation.

>
> I agree this is not elegant, just searching for solution. But in fact
> m_array is one instance only too, so setting it's size in count
> elemnts everytime clsTest object is created should not break anything.
> Worse side of that is, that it is not set at all if no clsTest object
> is created.
>
>> In fact, it seems that you are looking for something else.
>> make count_elements a public member of clsTest and you will no longer
>> get an error that clsTest::m_array is private at the initialization.

>
> My first attemption was to make private field in clsTest:
>
> private:
> static const size_t m_count_elements;
>
> I cannot initiazlie it in the header:
>
> private:
> static const size_t m_count_elements = _countof(m_array);
>
> because there is no size of m_array specified (wat it important for
> the problem) in the clsTest definition. m_count_elements does not need
> to be public but it is important to be static (this is value for one
> m_array only) and expectation is to be const.
> But when trying to initialize it just after m_array is initialized in
> cpp file
> const size_t clsTest::m_count_elements = _countof(clsTest::m_array);
> get error that clsTest::m_array is not accessible. I think the issue
> here is _counof macro, that is defined in stdblib probably in VC++
> only. Am I correct?


The following works fine with gcc 4.1.2:

/* begin test.cpp */
#include <cstddef>

class clsElement
{
private:
int m_val;
public:
clsElement(int val) : m_val(val) {}
};

class clsTest
{
public:
clsTest() {}
virtual ~clsTest() {}
private:
static clsElement m_array[];
static size_t const m_count_elements;
};

clsElement clsTest::m_array[] = {clsElement(0), clsElement(1), clsElement(2)};
size_t const clsTest::m_count_elements = sizeof m_array / sizeof m_array[0];

int main()
{
clsTest clstest;
return 0;
}
/* end test.cpp */

woyt.a 02-11-2013 07:20 AM

Re: access violation on static nonst
 
Hi,
> The following works fine with gcc 4.1.2:

thankns fo answer. I have realized that it works under gcc 4.7 too. But does not work under VS2010. Do You know why?
Best regards,
woyt.a


All times are GMT. The time now is 05:37 AM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57