C Pointer for Struct - Segmentation fault - c

I am having problems with this program. It's very simply. I need to assign values to my struct from the pointers I created, but I keep getting a segmentation fault. Any ideas what I'm doing wrong:
#include <stdio.h>
#include <stdlib.h>
struct problem37
{
int a;
int b;
int c;
};
int main()
{
printf("Problem 37\n");
//create struct
struct problem37 myStruct;
//create the pointer
int* p;
int* q;
int* r;
*p = 1;
*q = 5;
*r = 8;
//read the data into the struct using the pointers
myStruct.a = *p;
myStruct.b = *q;
myStruct.c = *r;
printf("%d\n", myStruct.a);
printf("%d\n", myStruct.b);
printf("%d\n", myStruct.c);
return 0;
}

Your are assigning a value to *p, *q and *r, but they are not initialized: they're pointers pointing to random memory.
You need to initialize them, either assigning them a new value allocated in the heap (with malloc):
int *p = (int*) malloc( sizeof(int) );
*p = 1;
or making them point to an already existent value:
int x;
int *p = &x;
*p = 1; // it's like doing x=1

Your problem is that you write at random memory locations since you do not initialize your pointers nor allocate memory.
You could do the following:
int* p = malloc(sizeof(int));
int* q = malloc(sizeof(int));
int* r = malloc(sizeof(int));
Obviously you need to free them when you are done using them:
free(p);
free(q);
free(r);

You're not allocating memory to the pointer. Therefore when you're doing *p and *q and *r you're dereferencing a null pointer (or a random pointer). This leads to a segmentation fault. Use p = malloc(sizeof(int)); when you declare the variables.

Related

Pointer to struct in C, what is the content?

I was wondering if I have a code like this:
struct something{
int x;
float y;
};
int main(void)
{
struct something *p;
p = malloc(sizeof(struct something));
p->x = 2;
p->y = 5.6;
return 0;
}
what's the content of *p (with *) if called somewhere? Is it the address of the structure or what?
Here's an example of the usage of *p - that is, dereferencing the pointer:
#include <stdio.h>
#include <stdlib.h>
struct something {
int x;
float y;
};
int main(void) {
struct something *p;
p = malloc(sizeof *p);
p->x = 2;
p->y = 5.6;
struct something s;
s = *p; // dereference p and copy into s
free(p);
// now check s:
printf("%d, %.1f\n", s.x, s.y); // prints 2, 5.6
}
p is a pointer to struct something. *p will dereference that pointer to give the struct itself. But, here is the catch: struct (*p) is a composite data type, you need to use a . operator to get its member.
(*p).x = 2;
(*p).y = 5.6;
This can also be done without using the indirection operator (*) (as you did):
p->x = 2;
p->y = 5.6;

Allocate record with variable at negative offset

When allocating memory for a pointer to a record I also need space for an integer pointer located just before the allocated record. This pointer cannot be part of the record itself and it cannot be placed after the record. My current approach is the following:
#include <stdlib.h>
static int n;
struct { int f; } *p;
p = malloc(sizeof (int *) + sizeof *p);
if (p != NULL) {
p = (void *) ((int **) p + 1);
*((int **) p - 1) = &n;
}
Are the casts well defined? If not, what should I do instead?
Edit:
What I'm trying to achieve is to implement extensible records (OOP) and the integer pointer represent a type ID. An extended record should be compatible with its base type. However, I only need type ID:s for pointer to records. Here is a complete example:
#include <assert.h>
#include <stdlib.h>
struct T0 {
int f;
};
int T0ID;
struct T1 {
struct T0 base;
int g;
};
int T1ID;
int main(void)
{
struct T0 *x;
struct T1 *y;
y = malloc(sizeof (int *) + sizeof *y);
if (y != NULL) {
*((int **) y) = &T1ID;
y = (void *) ((int **) y + 1);
((struct T0 *) y)->f = 1;
y->g = 2;
}
x = (struct T0 *) y;
assert(x->f == 1);
return 0;
}
I'm not sure your approach is good. Especially I'm worried about changing the value of p. You'll need that value later when you need to free the memory.
I would wrap the int* and the struct together in another struct. Something like:
static int n;
struct someData { int f; };
struct wrapper {int* pn; struct someData data;};
struct someData* pd; // Pointer to the data struct
struct wrapper* pw = malloc(sizeof *pw);
if (pw != NULL) {
pw->pn = &n;
pd = &pw->data;
}
Your code, in which you cast (arbitrary) memory addresses to particular object types, is might yield undefined behaviour due to incorrect alignment (cf.
C standard draft):
6.3.2.3 Pointers
(7) A pointer to an object type may be converted to a pointer to a
different object type. If the resulting pointer is not correctly
aligned for the referenced type, the behavior is undefined.
You are having a pointer declared to be of type struct{int}* pointing to a (larger memory block), and then casting the pointer and doing arithmetic operations on the (casted) pointer. As it is not guaranteed that int * and struct{int}* are aligned the same way, it is not guaranteed that the behaviour is defined.
To avoid this, encapsulate your structure and the preceeding integer in another structure, e.g. as follows:
static int n;
struct data_struct {
int f;
};
struct enclosing_struct {
int *nPtr;
struct data_struct data;
};
int main() {
struct enclosing_struct *e = malloc (sizeof(struct enclosing_struct));
e->nPtr = &n;
struct data_struct *dataPtr = &e->data;
return 0;
}

Write a Struct to Binary File in C [duplicate]

I am having problems with this program. It's very simply. I need to assign values to my struct from the pointers I created, but I keep getting a segmentation fault. Any ideas what I'm doing wrong:
#include <stdio.h>
#include <stdlib.h>
struct problem37
{
int a;
int b;
int c;
};
int main()
{
printf("Problem 37\n");
//create struct
struct problem37 myStruct;
//create the pointer
int* p;
int* q;
int* r;
*p = 1;
*q = 5;
*r = 8;
//read the data into the struct using the pointers
myStruct.a = *p;
myStruct.b = *q;
myStruct.c = *r;
printf("%d\n", myStruct.a);
printf("%d\n", myStruct.b);
printf("%d\n", myStruct.c);
return 0;
}
Your are assigning a value to *p, *q and *r, but they are not initialized: they're pointers pointing to random memory.
You need to initialize them, either assigning them a new value allocated in the heap (with malloc):
int *p = (int*) malloc( sizeof(int) );
*p = 1;
or making them point to an already existent value:
int x;
int *p = &x;
*p = 1; // it's like doing x=1
Your problem is that you write at random memory locations since you do not initialize your pointers nor allocate memory.
You could do the following:
int* p = malloc(sizeof(int));
int* q = malloc(sizeof(int));
int* r = malloc(sizeof(int));
Obviously you need to free them when you are done using them:
free(p);
free(q);
free(r);
You're not allocating memory to the pointer. Therefore when you're doing *p and *q and *r you're dereferencing a null pointer (or a random pointer). This leads to a segmentation fault. Use p = malloc(sizeof(int)); when you declare the variables.

malloc of array in struct passed as argument

I would like to allocate memory for arrays that are members of a struct I need to use, inside a function that takes the struct as an argument.
arg->A.size=(int*) malloc(N*sizeof(int));
will not compile (request for member 'size' is something not a structure.
arg->A->size=(int*) malloc(N*sizeof(int));
will throw a segmentation fault error
Any help will be appreciated.
Here is the code, thanks:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// struct A
struct A {
int dim; // dimensions
int* size; // points per dim array
double* val; // values stored in array
int total; // pow(size,dim)
};
// struct B that uses A
struct B {
int tag;
struct A* A;
};
int function_AB(struct B* B);
int main(void){
struct B B;
function_AB(&B);
return 0;
}
int function_AB(struct B* arg){
int N=10;
arg->tag=99;
printf("tag assigned = %d \n", arg->tag);
arg->A->size=(int*) malloc(N*sizeof(int));
return 0;
}
You simply haven't allocated memory for struct A *A. Before assigning anything to A->size you would first need to do something like
B->A = malloc(sizeof(struct A));
The second case is correct, but crashes because the A inside the B declared in main has not been assigned a value. You probably want something like
struct A A;
struct B B;
B.A = &A;
function_AB(&B);
When you have structure pointer in another structure, first you need to allocate memory for that. then allocate the memory for structure members!
struct B {
int tag;
struct A* A;
};
Here A is a pointer to a structure called A. First allocate memory for this, then allocate memory for the elements of struct A
arg->A = malloc(sizeof(struct A));
then do-
arg->A->size = malloc(N*sizeof(int));
Try the following changes in your int function_AB(struct B* arg)-
int function_AB(struct B* arg){
int N=10;
arg->tag=99;
printf("tag assigned = %d \n", arg->tag);
arg->A = malloc(sizeof(struct A)); // First allocate the memory for struct A* A;
arg->A->size = malloc(N*sizeof(int)); // Allocate the memory for struct A members
arg->A->val = malloc(N*sizeof(double));
// do your stuff
// free the allocated memories here
free(arg->A->size);
free(arg->A->val);
free(arg->A);
return 0;
}
And don't cast the result of malloc()!

How to malloc "MyDef ** t" to a specific length, instead of "MyDef * t[5]" in C

A struct like the following works fine, I can use t after calling malloc(sizeof(mystruct)):
struct mystruct {
MyDef *t[5];
};
I want to be able to dynamically set the length of the array of MyDef, like the following:
struct mystruct {
MyDef **t;
int size;
};
What do I need to do additionally to malloc(sizeof(mystruct)) to get this to work, so I can do TestStruct->t[3] = something? Just getting a segmentation fault!
Thanks!
EDIT with code that causes seg fault, unless I'm blind this seems to be what the answers are so far:
#include <stdio.h>
typedef struct mydef {
int t;
int y;
int k;
} MyDef;
typedef struct mystruct {
MyDef **t;
int size;
} MyStruct;
int main(){
MyStruct *m;
if (m = (MyStruct *)malloc(sizeof(MyStruct)) == NULL)
return 0;
m->size = 11; //seg fault
if (m->t = malloc(m->size * sizeof(*m->t)) == NULL)
return 0;
return 0;
}
struct mystruct *s = malloc(sizeof(*s));
s->size = 5;
s->t = malloc(sizeof(*s->t) * s->size);
m = (MyStruct*)malloc(sizeof(MyStruct)) == NULL
What that does. Calls malloc, compares return of malloc to NULL. Then assigns the result of that comparison(a boolean value) to m.
The reason it does that is because '==' has a higher precedence than '='.
What you want:
if ( (m = (MyStruct *)malloc(sizeof(MyStruct))) == NULL)
...
if ( (m->t = malloc(m->size * sizeof(*m->t))) == NULL)
That happens because you do not allocate memory for array itself, only for pointer to this array.
So, first you have to allocate mystruct:
struct_instance = malloc(sizeof(mystruct));
and then you have to allocate memory for array of pointers to MyDef and initialize pointer in your struct
struct_instance->size = 123;
struct_instance->t = malloc(sizeof(MyDef*) * struct_instance->size);

Resources