1

In the below piece of code, I am not able to change the values of x and y individually. Can some one help me with assigning these values individually?

#include <stdio.h>

struct p
{  
    int x;
    int y;
};

int main()
{   
    int p2 = 55;
    int p3 = 99;
    //const struct p *ptr1 = {&p2,&p3};  --- giving the expected result
    const struct p *ptr1;
    ptr1->x = &p2;  //error
    ptr1->y = &p3;  //error
    printf("%d %d \n", ptr1->x, ptr1->y);
}

Note: I have searched for such an example, I could not able to find and I am running out of time. If the question is already asked, I am really very sorry to waste your time and please provide me the link for the same to refer.

2
  • The address of p2 and p3 seem to get cast to an integer value? What is the expected result? Commented Jun 29, 2015 at 7:02
  • So the problem is, when you try to dereference a const, unallocated pointer for writing compiler does not perform implicit cast from int * to int and write it silently. Commented Jun 29, 2015 at 7:08

3 Answers 3

6

Since the author seemed to want to change a struct that she was declaring const, this might in fact be a very relevant answer.

A common gotcha directly related to this question is that

const struct p *ptr1

is a pointer to a "const struct p", which means the pointer variable ptr1 can change and point to a different struct p later, but regardless of where it points, you can't write to members of the struct using that pointer (e.g. ptr1->x = blah;).

What some might be looking for is a pointer which is const, and thus can't ever point to a different piece of memory, after being assigned one at its initialization.

That would be

struct p * const ptr2 = ptr1   // whatever ptr1 currently points to, ptr2 will point to there, from now to forever (for the lifetime / scope of ptr2).
Sign up to request clarification or add additional context in comments.

Comments

4

There are two important issues to consider:

  1. const struct p* is a "pointer to const p", which means you cannot modify the instance it points to. It can point to a non-const object, but you can't use the pointer to modify said object.

  2. A pointer must point to a valid object before it can be de-referenced.

You need to create a valid p instance, then make the pointer point to it:

struct p x = {p2, p3};
const struct p *ptr1 = &x;

In this example, a p instance is created in automatic storage. You can also instantiate one dynamically using malloc if that suits your needs better. For example,

struct p *px = malloc(sizeof (struct p));
px->x = p2;
px->y = p3;
const struct p *ptr1 = px;

In both examples, you can modify the instance ptr1 points to via x and px respectively, but not via ptr1.

2 Comments

I need to change only some of the structure values, not for the whole structure
@Denise You can do that via x or px. Note that ptr1 doesn't allow modifications to the object it points to.
2
const struct p *ptr1 = {&p2,&p3}; //  --- giving the expected result

It compiles, but with this warning; and either way, it probably doesn't do what you want anyway:

warning: incompatible pointer types initializing 'const struct p *' with an expression of type 'int *' [-Wincompatible-pointer-types]

To create a constant pointer to struct, you could use this:

const struct p *ptr1 = &(struct p){p2, p3};

Quick note about lifetime:

If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.

5 Comments

Does the lifetime of the rvalue on the RHS get extended?
What is the life of temp object?
@Ja͢ck Either the lifetime of the temporary gets extended, in which case you should mention it in your answer, or it doesn't, in which case the code is illegal. I was asking a genuine question, in case this is one of the places where C differs from C++. In the latter, the code would be illegal.
@juanchopanza I've included a passage of the standard that should apply here; the lifetime here should be automatic within main(). Of course, I could be wrong .. :)
@Ja͢ck That seems right. So it does look like a C differs from C++ here. I'll remove some of my previous comments.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.