Change address of struct in C - c

Let's say that I was given a struct and I need to assign all of it's attributes to a particular address. The code below is giving me a conditional error, but i'm not trying to evaluate it.
struct header block_o_data;
block_o_data.a = 1;
block_o_data.b = 2;
void* startingAddress = sbrk(0);
&block_o_data = *address;
Please let me know what im doing wrong.

In the assignment to block_o_data, you're taking its address and trying to assign a value to it. The address of a variable is not an lvalue, meaning the expression cannot appear on the left side of an assignment.
You need to declare a pointer to a struct, then assign it the address of where the values actually live:
struct header *block_o_data;
void* startingAddress = sbrk(0);
block_o_data = startingAddress;

Suppose you have a struct like this:
struct mystruct {
int a;
char b;
};
then you probably need something like this:
// A pointer variable supposed to point to an instance of the struct
struct mystruct *pointer;
// This is a general address represented by void*
void *addr = some_function(0);
// Cast that general address to a pointer varibale pointing to
// an instance of the struct
pointer = (struct mystruct *) addr;
// Use it!
printf("%d", pointer->a);

Related

Struct pointer and its pointer attribute issue

Has this code undefined behaviour which means for s is mandatory to allocate memory or is ok this way ?
PS: what is the difference between
struct X* x = (struct X*)malloc(sizeof(struct X));
and
struct X* x = (struct X*)malloc(sizeof(x));
and
struct X* x = (struct X*)malloc(sizeof *x);
Thank you.
#include <stdio.h>
#include <stdlib.h>
struct X
{
int x;
char* s;
};
int main()
{
struct X* x = (struct X*)malloc(sizeof(struct X));
x->x = 10;
// x->s = (char*)malloc(10);
// memcpy...
x->s = "something";
printf("is ok?");
return 0;
}
Rather than throw my own interpretation at you i felt it would be more helpful to share a link that might clarify what you are aiming to achieve:
https://www.geeksforgeeks.org/new-vs-malloc-and-free-vs-delete-in-c/
When you create a pointer i see that you have added the pointer to your char* variable / struct, but when calling them the use of the ampersand & is used as a reference to the address in the memory.
But not applied quite right using the int variable when declaring it no '*' and then referencing the location using '&'.
This is fine. Since s is part of the struct, allocating memory for the struct allocates memory for s. I would strongly suggest changing the type of s to be a const pointer, since it points to a literal which, because it's a type of constant, cannot be modified.
You cannot do s[0]='n'; after this. You did not allocate any space to hold any string other than the unmodifiable literal "something".

Free the memory where a uintptr_t is pointing to

I have the following problem:
First of all I have struct:
struct Filehandler
{
const int id = 1;
};
Then I have two methods - one for creating a new Filehandler struct and one for deleting the struct. Because the whole code is part of a Webassembly Plugin for a Rust project, I have to use pointers.
So this is my method for allocating the struct:
uintptr_t newhandler() {
struct Filehandler* filehandler = (struct Filehandler*) malloc(sizeof(struct Filehandler));
uintptr_t *ptr = (uintptr_t *)&filehandler;
uintptr_t temp = (uintptr_t)ptr;
return temp;
}
I know this somehow looks confusing but I have to retrieve the address the pointer is pointing as value. Thats why im returning my pointer as value.
Now I want to create a function which deletes the struct. As parameter the function gets an uintptr_t:
void destroy_handler(uintptr_t ptr) {
........?
}
So my question is: Is it possible to delete the Struct filehandler, if I have a the pointer to it stored in a uintptr_t and give it as a value to the destroy_handler function. And if this is possible how do I do it?
Thank you guys!
const int id = 1; isn't valid C because you can't initialize members of a struct like that. In general, avoid const qualifiers of members but make an instance of the whole struct const instead.
uintptr_t newhandler() should be uintptr_t newhandler(void), the former is obsolete style and should not be used.
Casting the result of malloc is pointless. Consider struct Filehandler* filehandler = malloc (sizeof *filehandler); instead.
uintptr_t *ptr = (uintptr_t *)&filehandler; doesn't make any sense, you are casting the malloc:ed pointer's address which is a local variable. Drop the &.
uintptr_t temp = (uintptr_t)ptr; doesn't make any sense because you are casting the address of a local pointer again.
Fixed code should look something like:
struct Filehandler
{
int id;
};
const struct Filehandler FH = {.id = 1};
...
#include <stdlib.h>
uintptr_t newhandler (void)
{
struct Filehandler* filehandler = malloc(sizeof *filehandler);
if(filehandler == NULL)
{
return 0;
}
// optional line: memcpy(filehandler, &FH, sizeof FH);
return (uintptr_t)filehandler;
}
void destroy_handler(uintptr_t ptr)
{
free((void*)ptr);
}

Pointer to table of struct in C

I don't understand some piece of code in C, and couldn't find any similar question, so I hope you'll help me.
I have a struct table defined like this:
struct my_struct {
struct other_struct some_struct[N];
char some_char;
..
} my_struct[N];
In another function:
struct my_struct *ms;
And then is the part I don't understand:
ms = &my_struct[0];
How can I interpret this line?
ms is a pointer to the struct my_struct. It contains address of a struct my_struct variable. Here we assign to ms the already declared struct my_struct array's (also name my_struct) 0-th element's address.
& - address of operator. Which basically returns the address of a variable.
Now you can access my_struct[0] via ms.
Equivalently
ms->some_char = 'A' is same as my_struct[0].some_char='A'. To give a small example I can simplify this way.
struct a{
int z;
};
struct a array[10]; // array of 10 `struct a`
struct a* ptr = &array[0]; // ptr contains the address of array[0].
Now we can access array[0] via pointer ptr.
And ms is just a pointer to struct not pointer to a table of struct as you have mentioned in the question heading.

Casting struct * to int * to be able to write into first field

I've recently found this page:
Making PyObject_HEAD conform to standard C
and I'm curious about this paragraph:
Standard C has one specific exception to its aliasing rules precisely designed to support the case of Python: a value of a struct type may also be accessed through a pointer to the first field. E.g. if a struct starts with an int , the struct * may also be cast to an int * , allowing to write int values into the first field.
So I wrote this code to check with my compilers:
struct with_int {
int a;
char b;
};
int main(void)
{
struct with_int *i = malloc(sizeof(struct with_int));
i->a = 5;
((int *)&i)->a = 8;
}
but I'm getting error: request for member 'a' in something not a struct or union.
Did I get the above paragraph right? If no, what am I doing wrong?
Also, if someone knows where C standard is referring to this rule, please point it out here. Thanks.
Your interpretation1 is correct, but the code isn't.
The pointer i already points to the object, and thus to the first element, so you only need to cast it to the correct type:
int* n = ( int* )i;
then you simply dereference it:
*n = 345;
Or in one step:
*( int* )i = 345;
1 (Quoted from: ISO:IEC 9899:201X 6.7.2.1 Structure and union specifiers 15)
Within a structure object, the non-bit-field members and the units in which bit-fields
reside have addresses that increase in the order in which they are declared. A pointer to a
structure object, suitably converted, points to its initial member (or if that member is a
bit-field, then to the unit in which it resides), and vice versa. There may be unnamed
padding within a structure object, but not at its beginning.
You have a few issues, but this works for me:
#include <malloc.h>
#include <stdio.h>
struct with_int {
int a;
char b;
};
int main(void)
{
struct with_int *i = (struct with_int *)malloc(sizeof(struct with_int));
i->a = 5;
*(int *)i = 8;
printf("%d\n", i->a);
}
Output is:
8
Like other answers have pointed out, I think you meant:
// Interpret (struct with_int *) as (int *), then
// dereference it to assign the value 8.
*((int *) i) = 8;
and not:
((int *) &i)->a = 8;
However, none of the answers explain specifically why that error makes sense.
Let me explain what ((int *) &i)->a means:
i is a variable that holds an address to a (struct with_int). &i is the address on main() function's stack space. This means &i is an address, that contains an address to a (struct with_int). In other words, &i is a pointer to a pointer to (struct with_int). Then the cast (int *) of this would tell the compiler to interpret this stack address as an int pointer, that is, address of an int. Finally, with that ->a, you are asking the compiler to fetch the struct member a from this int pointer and then assign the value 8 to it. It doesn't make sense to fetch a struct member from an int pointer. Hence, you get error: request for member 'a' in something not a struct or union.
Hope this helps.

Is this use of struct pointers correct?

I have this struct:
typedef struct Grades {
int grade1;
int grade2;
int grade3;
int grade4;
int grade5;
}
I created a pointer to a Grades struct using
struct Grades *pointer;
and I have a function() that returns a (void *) pointer to a specific Grades struct.
How do I set my pointer to that specific struct using the (void *) pointer?
I was thinking:
pointer = &function();
but that gives me an error: "'&' requires l-value
Any ideas? And by the way, I can't modify the function so...
If function() returns a pointer, you should be able to just do
pointer = function();
pointer = function();
If function() is returning a void pointer, you don't need to take the address of it, it's already a pointer pointing to a Grades struct.

Resources