0

I have a code like below:

struct abc
{
    int *xyz;
}

void func1(abc *ptr, .... lots of other struct ptrs passed)
{
    func2(ptr->xyz) // some computation, only read from ptr->xyz
    ...
    ...
    func3(ptr->xyz) // some computation, ptr->xyz is only read
}

void main()
{ 
    abc *ptr;
    // memory is allocated properly here for ptr and ptr->xyz.
    func1(ptr,...);
}

Problem: Seg fault happens at func3, due to ptr->xyz=0x0. Till func2, ptr->xyz address is proper. and no other related code before func3. Not reproducible. Not much info from core dump regarding start of memory corruption, or valgrind.

Analysis: I ran GDB and used command awatch *(address of ptr->xyz) for normal working case. Throughout func1, func2, func3, we only read from ptr->xyz memory address. No write operation happens, in normal working scenario. So I believe this might be due to some other memory corruption overlap.

Question: If I pass as void func1(const abc *const ptr). I dont want to change address/data of abc or abc->xyz. Does "const" ensure that struct abc,abc->xyz always gets stored in some read-only segment in memory, and hence safe from any memory corruption ? maybe due to other struct memory address overlap write ?

Thanks!

isarma
  • 29
  • 3

1 Answers1

4

Does "const" ensure that struct abc,abc->xyz always gets stored in some read-only segment in memory, and hence safe from any memory corruption ?

No, not always. With const, diagnostics (warnings/errors) at compile time emit if code knowingly attempts to modify the variable.

If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined. C11 §6.7.3 6

Should code attempt, at run time, to modify a const variable, it might work, it may fail silently, it may crash the program. It is undefined behavior.

In OP's case, suspect code is writing outside bounds and into field xyz, so making xyz const is not going to help much.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 1
    You could emphasize the difference between a *const object* which is initialized at its point of definition, and a pointer to const *function parameter*. The *const object* may physically be in a read-only memory location. The *pointer* points to an existing object which itself may or may not be const. Declaring the pointer one way or another is only an indication of intent (and influences overload resolution). It does in no way change the character of the memory pointed to. – Peter - Reinstate Monica Jul 20 '16 at 15:50
  • @Peter A. Schneider 1 ) Yes, "The const object may physically be in a read-only memory location.", OP certainly knows that. OP wants to know if that is _always_ true - it is not. 2) Unclear on "influences overload resolution" on this C post. Perhaps you are thing of another language? `const` has a more subtle meaning in C than other languages. It is more like "read-only" than "constant". – chux - Reinstate Monica Jul 20 '16 at 16:03
  • (1) Oh. C. Yes, no overload resolution." (2) OP certainly knows that": I had the hunch that he wanted to prevent a memory overwrite by declaring the *pointer* to be pointing to a const object, without changing the object definition (note the " If I pass as void func1(const abc *const ptr)" from the post). That would, of course, not do anything. – Peter - Reinstate Monica Jul 20 '16 at 20:04
  • 1
    Thank you guys for the explanation. Guess I need to figure out the actual memory overwrite issue, rather than trying to cover it up! Thanks again.. – isarma Jul 21 '16 at 08:53