Access structure member char* using offsets - c

If I have a code:
typedef struct s_ {
int a;
char* b;
} s;
int main()
{
s* st = malloc(sizeof(s));
st->b = malloc(20*sizeof(char));
st->a = 1;
st->b = "foo";
}
Is it possible here to access data in char array using offset?
For example offset here is 4 bytes, I know it and can calculate using for example offsetof() macro, but I can't access data using pointer arithmetics like:
printf("%s", (char*)(st+4));
I would be very happy if someone could help here :)

The answer may be surprising: st+4 actually increments the pointer by 32 bytes!
This is because the type of st is struct s_ * and when you add 4 to that, it is incremented by 4 times the size of the struct.
In order to move by 4 bytes, you need to cast the pointer to char* first and then increment it.
Try this: printf("%s", *(char**)((char*)st + 4));
Edit:
Added *(char**).
It is needed because by incrementing the pointer, we don't get the beginning of the string, we get the address of the pointer to the beginning of the string.
So we need to cast it to the proper type and dereference it.

You can calculate the byte address of the char * element b (which is a char ** value) using (char *)st + offsetof(s, b); therefore you can access the string using code like this:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct s_
{
int a;
char *b;
} s;
int main(void)
{
s *st = malloc(sizeof(s));
st->b = malloc(20 * sizeof(char));
st->a = 1;
strcpy(st->b, "foo");
char *str = *(char **)((char *)st + offsetof(s, b));
printf("[%s]\n", str);
return 0;
}
The output is a line containing [foo].
Now you know why you don't want to have to do this — let the compiler solve it for you:
printf("[%s]\n", st->b);
This question is getting close to Is it possible to dynamically define a struct in C?

If you use printf("%s", (char*)(st+4));,result have been offset 4*struct s
You want to printf the fourth character,could write like this
char *ptr = null;
ptr = st;
printf("[%s]",ptr);

Related

Referencing a struct member with pointer arithmetic

I've got a struct definition,
struct liste{
unsigned int size;
unsigned int capacity;
char* data;
};
and an instance,
struct liste lst = {3, 4, "hi"};
and what I'm trying to do is get the data member without directly calling lst.data. So far I've been able get a pointer, dataC ;
char* dataC = (char *) ((char *)&lst + 2 * sizeof(unsigned int));
whereby printing dataC and &lst.data as pointers gives the same output. I thought dereferencing dataC and casting the result to a char * would yield a pointer identical lst.data but I get a segfault.
Is there something I'm missing??
According to your code, dataC does not store the address of the data "hi", but the address of the pointer of lst.data. You can see the code below. dataC is the address of lst.data. *dataC is the address of the string "hi", the same as lst.data.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<stdint.h>
struct liste{
unsigned int size;
unsigned int capacity;
char *data;
};
int main()
{
struct liste lst = {3, 4,"hi"};
char **dataC = (char **) ((char *)&lst + 2 * sizeof(unsigned int));
printf("datac = %s\n",(*dataC));
}
Your code is neither portable nor rugged, because there might be struct padding inside the struct. If you need to do something like you attempt here, you should be using the offsetof macro, which is used to get the byte offset of a member inside a struct. Example:
#include <stdio.h>
#include <stddef.h> // offsetof
struct liste{
unsigned int size;
unsigned int capacity;
char* data;
};
int main (void)
{
struct liste lst = {3, 4, "hi"};
char** ptrptr = (char**) ((char*)&lst + offsetof(struct liste, data)) ;
puts(*ptrptr);
}
Notably the (char*)&list part has nothing to do with the data we are looking for being of char type. This is simply a way of iterating through a larger data type byte by byte, which C allows if we use character pointers. We end up with a character pointer pointing at the location of (the pointer) data inside the struct. By casting the result to char**, we make it clear that whatever we are pointing at is a char*.
Similarly, we could get the capacity member like this:
unsigned int** pp_cap = (unsigned int**) ((char*)&lst + offsetof(struct liste, capacity)) ;
printf("%d\n", *pp_cap);

Allocating memory to a struct member pointer in C

I have a structure with a member that I need to pass to a function by reference. In that function, I'd like to allocate memory & assign a value. I'm having issues somewhere along the line - it seems that after the code returns from allocateMemory, the memory that I had allocated & the values that I assigned go out of scope (this may not be exactly what is happening, but it appears to be the case).
#include <stdio.h>
#include <stdlib.h>
typedef struct myStruct_t
{
char *myString;
} myStruct;
void allocateMemory(void *str);
int main(void) {
myStruct tmp = {
.myString = NULL
};
myStruct *p = &tmp;
allocateMemory(p->myString);
//allocateMemory(&(p->myString)); //also tried this
printf("%s", p->myString);
return 0;
}
void allocateMemory(void *str)
{
str = malloc(8);
((char *)str)[0] = 'a';
((char *)str)[1] = 0;
}
If I print the value of str inside of allocateMemory, the 'a' is successfully printed, but if I attempt to print p->myString in main, my string is empty.
Can anyone tell me what I'm doing wrong?
You need to pass address of the structure member and then you can change (aka allocate memory) to it. In your version of the function, you are not taking a pointer not reference of a pointer, so you can change the content of memory referenced by the pointer but not the pointer itself.
So change your function to
void allocateMemory(char **ret_str)
{
char *str = malloc(8);
str[0] = 'a';
str[1] = 0;
*ret_str = str;
}
And then call it as
allocateMemory(&p->myString)
An alternative way of writing the same function Rohan did, eliminating the need to define any new variables:
void allocateMemory(char **str, size_t size) {
*str = malloc(size);
(*str)[0] = 'a';
(*str)[1] = '\0';
}
Note that I pass a size parameter to justify using malloc() in the first place.

What is a good way to allocate a sized string buffer on the stack?

Using pure C (and the C-preprocessor) I would like to create a string buffer that includes a length parameter, so that I could pass it around easily and any functions that operate on it could do so without danger of writing past the end. This is simple enough:
typedef struct strbuf_t_ {
int length;
char str[1];
} strbuf_t;
but then if I want a small scratch space on the stack to format some output text, there is no trivial way to allocate a strbuf_t on the stack. What I would like is some clever macro that allows me to do:
STRBUF(10) foo;
printf("foo.length = %d\n", foo.length); // outputs: foo.length = 10
strncpy(foo.str, "this is too long", foo.length);
Unfortunately I don't seem to be able to do that. The best I've come up with is:
#define STRBUF(size, name) \
struct {\
strbuf_t buf;\
char space[size - 1];\
char zero;\
} name ## _plus_space_ = { .buf={.length=size}, .space="", .zero='\0'};\
strbuf_t *name = &name ## _plus_space_.buf
int main(void)
{
STRBUF(10, a);
strncpy(a->str, "Hello, world!", a->length);
printf("a->length = %d\n", a->length); // outputs: a->length = 10
puts(a->str); // outputs: Hello, wor
}
This meets all of the requirements I listed, but a is a pointer not the structure itself, and the allocation is certainly not intuitive.
Has anyone come up with something better?
I think you are already pretty close to a solution. Just keep a char* in your struct and allocate it via char-array. In order to have the save trailing zero at the end of string, just allocate an extra char additional to the size and initialize the whole array with zeroes.
typedef struct
{
int length;
char* str;
} strbuf_t;
#define STRBUF(varname, size) \
char _buffer_ ## varname[size + 1] = {'\0'}; \
strbuf_t varname = { size, _buffer_ ## varname }
int main()
{
STRBUF(a, 10);
strncpy(a.str, "Hello, world!", a.length);
printf("a.length = %d\n", a.length);
puts(a.str);
}
Perhaps the following. Allocate the memory with an aligned VLA and then overlay.
typedef struct strbuf_t_ {
int length;
char str[];
} strbuf_t;
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdalign.h>
int main(void) {
char *s = "Hello";
size_t length = strlen(s);
size_t n = sizeof (strbuf_t) + length + 1;
_Alignas(strbuf_t) unsigned char mem[n];
strbuf_t *xx = (strbuf_t*) mem;
xx->length = length;
memcpy(xx->str, s, n+1);
printf("int:%zu s:%zu n:%zu mem:%zu\n",
sizeof xx->length, sizeof (strbuf_t), n, sizeof mem);
return 0;
}
Output
int:4 s:4 n:6 mem:10
Note: C99 allows the last struct member to have an indefinite array count of []

Access structure variables in a loop

My requirement is that i create a structure with variables like
struct stu{
char var_01;
char var_02;
.
.
char var_30;
}stu_t;
and not use an array instead like
char var[30];
With the above requirement established, i can't figure how to access these variables in a loop by concatenating var_ + iterating integer. I know i cant just concatenate, store in a variable and use that variable to access.
Appreciate any help. Thanks!
Variable names have no meaning at run-time in a C program. The names are only for humans, they are removed during compilation. That's why you can't build variable names and somehow use those.
The solution is to use an external array with pointers:
stu_t my_stu;
char * vars[30];
vars[0] = &my_stu.var_01;
vars[1] = &my_stu.var_02;
/* ... and so on ... */
Then you can use vars to access into my_stu:
*vars[0] = 'u';
printf("var_01 is '%c'\n", my_stu.var_01);
Of course this isn't very pretty, but that's what you get.
You can use a pointer for that:
struct stu{
char var_01;
char var_02;
/* ... */
char var_30;
}stu_t;
char* ptr = &stu_t.var_01;
while(ptr <= &stu_t.var_30)
{
*ptr = '0';
printf("Character #%ld = %c \n", ptr - &stu_t.var_01, *ptr);
ptr++;
}
You can use union but it's rather "ugly" hack and I wouldn't recommend it, but if you really want it... (Still, it requires using arrays somewhere! Union will make structure and array use the same location in memory.) Example:
#include <stdio.h>
union Test
{
struct
{
char var_00;
char var_01;
char var_02;
char var_03;
char var_04;
};
char var[5];
};
int main()
{
union Test t;
t.var_01 = 'a';
printf("%c\n", t.var[1]);
return 0;
}
It outputs a.
Anyway, it's better to simply use array. Your requirement is kind of weird...
If your structure only contains chars, you can do this:
typedef struct stu_s {
char a;
char b;
char c;
} stu_t;
int main()
{
stu_t my_struct;
char *ptr = (char *)(&my_struct);
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("%hhd %hhd %hhd\n", my_struct.a, my_struct.b, my_struct.c);
}

initialize the struct pointer

typedef struct
{
char *s;
char d;
}EXE;
EXE *p;
For the above struct how do I initialize the structure with pointer? I know for a non-pointer we do EXE a[] = { {"abc",1}, {"def",2} }; . Similarly Is it possible with a pointer after allocating the memory? Say like p[] = { {"abc",1},.. so on} . Basically I want to initialize dynamically. Thanks.
We can initialise the structure with pointer as below
example:
int i;
char e[5]="abcd";
EXE *p=malloc(sizeof(*p));
for(i = 0;i < 5;i++)
*(p+i)=(EXE){e,i+48};
First you need to allocate some memory for that char * and after that use strcpy library function to copy data for structure element.
p->s = strcpy(s,str); //where str source, from where you need to copy the data
I hope this will help. Though I can give you full code for that, But I want you to try.
You can use this
Dynamically allocate C struct?
and it is a duplicate question.
You have to understand how do allocated pointer works:
Suppose you've allocated memory for three structs Ptr = malloc(3*sizeof(EXE)).
Then when you add 1 to Ptr, it comes to the next struct. You have a block of memory divided by 3 (3 smaller blocks of memory for each struct).
So, need to access to the elements of the 1st struct and then move the pointer to the next one.
Here you can understand how it works:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *s;
char d;
} EXE;
int main()
{
int i;
EXE *Ptr;
Ptr = malloc(3*sizeof(EXE)); // dymnamically allocating the
// memory for three structures
Ptr->s = "ABC";
Ptr->d = 'a';
//2nd
Ptr++; // moving to the 2nd structure
Ptr->s = "DEF";
Ptr->d = 'd';
//3rd
Ptr++; // moving to the 3rd structure
Ptr->s = "XYZ";
Ptr->d = 'x';
//reset the pointer `Ptr`
Ptr -= 2; // going to the 1st structure
//printing the 1st, the 2nd and the 3rd structs
for (i = 0; i < 3; i++) {
printf("%s\n", Ptr->s);
printf("%c\n\n", Ptr->d);
Ptr++;
}
return 0;
}
Notice:
- If you have a variable of a struct use . opereator to access to the elements.
- If you have a pointer to a struct use -> operator to access to the elements.
#include <stdio.h>
#include <stdlib.h>
struct EXE {
int a;
};
int main(){
struct EXE variable;
struct EXE *pointer;
pointer = malloc(sizeof(struct EXE)); // allocating mamory dynamically
// and making pointer to point to this
// dynamically allocated block of memory
// like here
variable.a = 100;
pointer->a = 100;
printf("%d\n%d\n", variable.a, pointer->a);
return 0;
}

Resources