access violation on static nonst

W

woyt.a

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
 
I

Ike Naar

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?
 
D

Dombo

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.
 
W

woyt.a

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
 
B

Balog Pal

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.
 
V

Victor Bazarov

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
 
M

Marcel Müller

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
 
W

woyt.a

clsTest::clsTest()
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
 
I

Ike Naar

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.


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 */
 
W

woyt.a

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
 
I

Ike Naar

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

No, because it is not clear what you mean by "does not work".
Can you post the code, and the errormessages from the compiler
and/or the runtime errors?
 
Ö

Öö Tiib

No, because it is not clear what you mean by "does not work".
Can you post the code, and the errormessages from the compiler
and/or the runtime errors?

He can't post any compile-time or run-time errors.
The code that you posted compiles and runs with VS2010.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top