access violation on static nonst

Discussion in 'C++' started by woyt.a, Feb 9, 2013.

  1. woyt.a

    woyt.a Guest

    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
    woyt.a, Feb 9, 2013
    #1
    1. Advertising

  2. woyt.a

    Ike Naar Guest

    On 2013-02-09, woyt.a <> 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?
    Ike Naar, Feb 9, 2013
    #2
    1. Advertising

  3. woyt.a

    Dombo Guest

    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.
    Dombo, Feb 9, 2013
    #3
  4. woyt.a

    woyt.a Guest

    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
    woyt.a, Feb 9, 2013
    #4
  5. woyt.a

    Balog Pal Guest

    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.
    Balog Pal, Feb 9, 2013
    #5
  6. 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
    Victor Bazarov, Feb 9, 2013
    #6
  7. 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
    Marcel Müller, Feb 10, 2013
    #7
  8. woyt.a

    woyt.a Guest

    > > 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
    woyt.a, Feb 10, 2013
    #8
  9. woyt.a

    Ike Naar Guest

    On 2013-02-10, woyt.a <> 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 */
    Ike Naar, Feb 10, 2013
    #9
  10. woyt.a

    woyt.a Guest

    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
    woyt.a, Feb 11, 2013
    #10
  11. woyt.a

    Ike Naar Guest

    On 2013-02-11, woyt.a <> wrote:
    > 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?
    Ike Naar, Feb 11, 2013
    #11
  12. woyt.a

    Öö Tiib Guest

    On Monday, 11 February 2013 17:30:12 UTC+2, Ike Naar wrote:
    > On 2013-02-11, woyt.a <> wrote:
    >
    > > 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?


    He can't post any compile-time or run-time errors.
    The code that you posted compiles and runs with VS2010.
    Öö Tiib, Feb 11, 2013
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. news
    Replies:
    0
    Views:
    419
  2. F. Prefect
    Replies:
    5
    Views:
    1,033
    Steven Cheng[MSFT]
    Oct 10, 2004
  3. Doug Trammell

    JNI Access Violation in jvm.dll

    Doug Trammell, Mar 4, 2004, in forum: Java
    Replies:
    5
    Views:
    8,117
    Chris Uppal
    Mar 5, 2004
  4. Allen
    Replies:
    9
    Views:
    394
  5. marvind
    Replies:
    4
    Views:
    419
    Paul Groke
    Jul 14, 2005
Loading...

Share This Page