I met a very strange problem.
I defined a struct and passed it as a const pointer into a function. The code is like bellow.
typedef struct a{
char str1[256];
...
int x;
}a_t;
int f(..., const a_t *a){...}
a_t a;
...
a.x = 1;
f(..., &a);
...
The problem is once it enters the f(), I will print out the variable a->x, which is always 0!??
But if I move the struct member x to the top of the struct (before other members), it will be 1, which is correct.
Are there any tricks or traps for using struct pointer as the parameter?
[EDIT1] The printf is called in the 1st line of function f()
Cannot comment so I will suggest debugging option. Can you please add print of the struct element x address in the function and before. If it is the same someone is changing it, otherwise we are not looking at the same value.
typedef struct a{
char str1[256];
...
int x;
}a_t;
int f(..., const a_t *a)
{
printf("X value %d, address %p", a->x, &(a->x));
...
}
a_t a;
...
a.x = 1;
printf("X value %d, address %p", a.x, &(a.x));
f(..., &a);
...
Also detail view of the function could help
Related
How can I realloc a double pointer inside a struct to another struct?
The double pointer is not used as a 2d array.
Code example.
struct x_tag {
int a;
int b;
};
typedef struct x_tag x_t;
struct y_tag {
x_t ** p;
int n;
};
typedef struct y_tag y_t;
/////////////////////////////////
y_t * d = malloc(sizeof(*d));
x_t * c = malloc(sizeof(*c));
d->p = &c;
/////////////////////////////
d->p = realloc(d->p, d->n*sizeof(x_t)); doesn't work.
d->p[0] = realloc(d->p[0], d->n*sizeof(x_t)); doesn't work.
*(d->p) = realloc(*(d->p), d->n*sizeof(x_t)); doesn't work.
*(d->p)[0] = realloc(*(d->p)[0], d->n*sizeof(x_t)); doesn't work.
Any ideas?
///////More info////////
The struct was not defined by me, but unfortunately I need to use this. Double pointers does not make sense to me either in this case.
The main idea is to change the size of (y_t **p) dinamically. The program should change the double pointer size every time another struct (x_t) is added.
|*d|--->|struct y_t|--->|**p|--->|*p|--->|struct x_t [0]|
|----->n |----->|struct x_t [1]|
|----->|struct x_t [2]|
I change the code to:
y_t * d = malloc(sizeof(*d));
d->p = malloc(sizeof(*d->p));
d->p[0] = malloc(sizeof(*d->p[0]));
Not working.
Code
typedef struct
{
int *x;int *y;
}point;
void move(point *p)
{
(*p).x=(*p).x+1;
(*p).y=(*p).y+1;
}
int main()
{
point p;
p.x = 10;
p.y = 5;
printf("%d, %d\n", p.x, p.y);
move(&p);
printf("%d, %d\n", p.x, p.y);
return 0;
}
Detail
I want to output 10,5 and 11,6 but it shows me 10,5 and 15,9. What's wrong with my code?
You have very little idea of what a pointer is. int* means it will contain the address of the int variable. p.x = 10 is saying that, assign 10 to this pointer variable. Then you are printing that pointer with wrong format specifier.
Then you have incremented those pointer. Accessing this would be disaster. And it's not strange that +1 on pointer will move it by sizeof(int). So the value you saw is 14 and 9.
typedef struct {int x;int y;}point;
This is what you have wanted for sure. Also other thing that is already mentioned is (*p).x = p->x. That's it.
You are wrong when you said output is 15,9 it will be 14,9. sizeof(int) = 4 in your system. To provide some more information pointers should be printed using %p format specifier like this.
int *p;
...
printf("%p\n",(void*)p);
I implemented this code and i got the output like this 10,5 and 14,9
there is 2 alternative ways to get the output like this 10,5 and 11,6
typedef struct
{
int *x;int *y;
}point;
replace the code with this :
`typedef struct
{
int x;int y;
}point;`
or
typedef struct
{
char *x; char *y;
}point;
Is what am I trying to do in C possible?
#include <stdio.h>
#include <stdlib.h>
struct foo{
int const * const a; // constPtrToConst is a constant (pointer)
// as is *constPtrToConst (value)
};
struct faa{
int b;
};
int main(void){
struct foo *x = (struct foo*)malloc(sizeof(struct foo));
struct faa *y = (struct faa*)malloc(sizeof(struct faa));
x->a = &(y->b); // error: assignment of read-only member ‘a’ [that's ok]
// (I)
x->a++; // It should not do this either...
printf("%d,\t%p\n", *(x->a), x->a); // (II)
free(x);
free(y);
}
How can I initialize (I) and could I get this (II)?
Sorry is not assign is initialize with that pointer.
This is what I want to get but dynamically.
#include <stdio.h>
struct foo{
int const * const a;
};
int main(void){
int b = 5;
struct foo x = {
.a = &b
};
printf("%d\n", *(x.a));
}
This is how I solve it.
I don't know if is the best choice.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct foo{
int const * const a;
};
struct foo* newfoo(int *var){
struct foo *tempD = malloc(sizeof(struct foo));
struct foo tempS ={
.a = var
};
memcpy(tempD, &tempS, sizeof(struct foo));
return tempD;
}
int main(void){
int b = 5;
struct foo *z = newfoo(&b);
printf("%d,\t%p\n", *(z->a), z->a);
// this is equivalent to printf("%d,\t%p\n", b, &b);
free(z);
}
int const * const a; is a type of variable which is constant means that it cannot be changed (second const), while first const means that it points to constant data.
Change your structure to:
struct foo{
const int* a;
};
Now you can assign value to a but you cannot modify value where a points.
struct foo myFoo;
myFoo.a = (int *)5; //a points to location 5 now, valid
*myFoo.a = 4; //Try to modify where a points = invalid and error
What is the difference between const int*, const int * const, and int const *?
You have to use memcpy in this case; you can't assign through a const expression:
int *temp = &y->b;
memcpy((void *)&x->a, &temp, sizeof temp);
In order to effect x->a++ you could do:
int *temp;
memcpy(&temp, &x->a, sizeof temp);
++temp;
memcpy((void *)&x->a, &temp, sizeof temp);
You can't assign to x->a after initialization, so you would have to do something silly like:
struct faa *y = (struct faa*)malloc(sizeof(struct faa));
struct foo tmp = {&y->b};
struct foo *x = (struct foo*)malloc(sizeof(struct foo));
memcpy(x, &tmp, sizeof *x);
This is the same scenario:
I locked the door and threw away the key since nobody including myself should ever open that door in any situation.
Immediately after doing that, I noticed that I cannot open the door!
I need to open this door! How do I do that? I threw away the key.
You have to 1) know what you are doing, and 2) don't do things that you actually don't want to do, including not making a program design specification that contradicts the actual needs of the program.
Simply change the declaration to int const* a; if you intend to change where that pointer points at.
Why not typecasting. The following code will print 6.
int main()
{
int x = 5;
const int* c{ &x};
int* p{( int*) c};
*p = 6;
std::cout << x << std::endl;
}
To explain more, I have two structures-'first' and 'second' having common variables 'jack' and 'jill'. I want to print jack via a pointer based on if-else condition.
I understand at the time of printing I have to typecast the void pointer. But whether the pointer points to struct a or b is decided on run time.
It is a basic C code. How to overcome this?
Code
#include <stdio.h>
int main(void)
{
typedef struct one
{
int jack;
float jill;
}a;
typedef struct two
{
int jack;
float jill;
char something;
int something1;
}b;
a first;
b second;
void *z;
if(1)
{
a* z;
z = &first;
printf("First one");
}
else
{
b* z;
z = &second;
printf("Second one");
}
printf("%d\n", z->jack);
return 0;
}
Error
prog.c:36:17: warning: dereferencing 'void *' pointer printf("%d\n", z->jack); prog.c:36:17: error: request for member 'jack' in something not a structure or union
You get a compiler warning since the compiler does not understand z->jack since z is a void * (note that the declarations a* z and b* z are not valid outside the scope of the if and else block).
To overcome this you can use a function printJack as shown in the following listing:
#include <stdio.h>
typedef struct one
{
int jack;
float jill;
}a;
typedef struct two
{
int jack;
float jill;
char something;
int something1;
}b;
void printJack(void *pStruct, int type)
{
switch (type)
{
case 1:
printf("jack: %d\n", ((a *)pStruct)->jack);
break;
default:
printf("jack: %d\n", ((b *)pStruct)->jack);
break;
}
}
/*
** main
*/
int main(void)
{
a first;
b second;
void *z;
first.jack = 5;
second.jack = 4892;
printJack(&first, 1);
printJack(&second, 0);
z = &first;
printJack(z, 1);
return (0);
}
I've written code like this often and experienced a lot of trouble with it. Not at the time of implementing, since you are knowing what you are typing at that moment but let's say a few years later if you need to extend your code. You will miss a few places where you cast from void * to a * or b * and you'll spend a lot of time debugging what's going on...
Now I'm writing things like this in the following way:
#include <stdio.h>
typedef struct header
{
int jack;
float jill;
} h;
typedef struct one
{
struct header header;
/* what ever you like */
}a;
typedef struct two
{
struct header header;
char something;
int something1;
/* and even more... */
}b;
void printJack(void *pStruct)
{
printf("jack: %d\n", ((struct header *)pStruct)->jack);
}
/*
** main
*/
int main(void)
{
a first;
b second;
void *z;
first.header.jack = 5;
second.header.jack = 4892;
printJack(&first);
printJack(&second);
v = &first;
printJack(v);
return (0);
}
As you've noticed I have declared a new struct header which covers the the common parts of struct one and struct two. Instead of casting the void * to either a * or b * a "common" cast to struct header * (or h *) is done.
By doing so you can easily extend the "common attribtues" of the structs or you can implement further structs using this header and function printJack still will work. Additionally there is no need for attribute type anymore making is easier to call printJack. You can even change the type of jack without needing to change it in various places within your code.
But remember that struct header needs to be the first element of the structs you use this mechanism. Otherwise you will end up with a few surprises since you are using memory which does not contain the data of the struct header...
I have the following code:
typedef struct {
double x, y;
} point_t ;
typedef struct {
point_t a, b, c;
} triangle_t;
int read_point(point_t * const point) {
int status = scanf(" (&lf,&lf)", &point_t.x, &point_t.y);
return(status);
}
I'm trying to read an x and y coordinate that the user enters for the vertexes of a triangle (Points a, b and c.) However, I'm getting a weird error underlining both instances of "point_t" in the scanf function.
Type name is not allowed.
What's going on?
Change it to:
int status = scanf(" (%lf,%lf)", &(point->x), &(point->y));
Remember to use the variable name point, not the type name point_t. It also important to note that you must use the operator -> on pointer types (it is equivalent to dereferencing it and then using the member operator [p->x == (*p).x]).
try this code
typedef struct {
double x;
double y;
} point_t ;
typedef struct {
point_t a;
point_t b
point_t c;
} triangle_t;
int read_point(point_t * point) {
int status = scanf(" (&lf,&lf)", point->x, point->y);
return(status);
}
I think in struct, you should declare each field with it's type; multiple declaration as int x,y doesn't work.
Secondly, you are passing a pointer so to access you should use the name of your argument ( "point" is this case) this way point->field or (*point).field and not &point !