how to access the struct? - c

struct result {
int number;
int length;
};
struct result findLongestSeq(int intarray[], int size) {
result->number // undefined symbol
}
how to access the struct result inside the function findLongestSeq?
thanks

struct result {
int number;
int length;
};
struct result findLongestSeq(int intarray[], int size) {
struct result result;
result.number = 0;
result.length = 42;
return result;
}
If you are dealing with struct result foo then you access its members via foo.number.
If however you are dealing with a pointer to foo (struct result *foo) then you access its members via foo->number.
If you were to manually allocate your result struct via
struct result *result = (struct result *)malloc(sizeof (struct result));
Then you'd have to access its members via result->number (and would be responsible for freeing it once not used anymore).
Further more I'd rather use this for the sake of better readability:
typedef struct {
int number;
int length;
} ResultStruct;
This way you can then use ResultStruct result; instead of redundant and verbose struct result result;.

You have to keep in mind that by simply typing
struct result {
int number;
int length;
};
you only define how a struct with name result actually looks like, i.e. of what parts it is made up. This is a general definition, but you have variable of that type yet.
To access values of this struct you have to create a variable by
struct result myResult;
or however you want to call it. At this point you are able to access the members of this struct with myResult.number

Related

accessing a value in return struct

if you have a function that returns a struct, is it then possible to access on of the internal values in struct that is returned, without having to handling the whole struct.
The code could look something like this;
struct myStruct
{
int value1;
int value2;
};
myStruct functionReturningStruct(void);
....
value2 = functionReturningStruct().value2
if it's possible in anyway, how?
Why don't you test?
#include <stdio.h>
struct myStruct
{
int value1;
int value2;
};
struct myStruct functionReturningStruct(void)
{
return (struct myStruct){10, 20};
}
int main(void)
{
int value = functionReturningStruct().value2;
printf("%d", value);
return 0;
}
It's possible.
Implementations I found use an implicit first argument of functionReturningStruct() which points to the structure, that is temporary allocated by the compiler on call point.
Indeed, it is equivalent to
{
struct myStruct __temp_myStruct;
__actual_functionReturningStruct(&__temp_myStruct);
value2 = __temp_myStruct.value2;
}

Dynamic allocation of union of structs

I am trying to create a union of 2 structs (dfp and affine) and want to allocate them dynamically. I am getting errors in creating particular struct array inside union. Am I declaring union in right way?
#include <stdio.h>
#include <stdlib.h>
struct{
int fp;
}dfp;
struct{
int scale;
int zp;
}affine;
union{
struct dfp *df;
struct affine *af;
}quant;
struct member{
int total;
union quant arr;
};
int main(void) {
// your code goes here
struct member* ptr;
ptr = (struct member *)malloc(sizeof(struct member));
ptr->total = 2;
int type = 0;
if(!type){
ptr->arr->df = (struct dfp*)malloc(ptr->total*sizeof(struct dfp)); //error
for(int i=0;i<2;i++){
ptr->arr->df->fp[i] = 10;
}
}
else{
ptr->arr->af = (struct affine*)malloc(ptr->total*sizeof(struct affine)); //error
for(int i=0;i<2;i++){
ptr->arr->af->scale[i] = 10;
ptr->arr->af->zp[i] = 20;
}
}
return 0;
}
Most issues have already been pointed out by others separately. This is my attempt at writing a complete answer with explanations and advice.
First off, please check your exact compiler warnings and errors. These are your best help in resolving these kind of issues.
The program does not contain a union of structs, but a union of pointers to structs.
The program's definitions are not correct. Taking dfp as an example. This, struct { int fp; } dfp;, defines an anonymous struct with the the variable name dfp. The name of the struct should go before the struct declaration list, e.g. struct dfp { int fp; };. See here or see the C standard specifications.
Judging by the code in main, the member variables of the structs should be arrays of size 2 instead of single ints.
The operator -> is for "member access using a pointer". Since arr is not a pointer, use a dot (.) to access its members. See here.
Dynamically allocated memory must be free'd, or else the program will have one or more memory leaks.
Here is the full code with all mentioned corrections:
#include <stdio.h>
#include <stdlib.h>
struct dfp {
int fp[2];
};
struct affine {
int scale[2];
int zp[2];
};
union quant {
struct dfp *df;
struct affine *af;
};
struct member {
int total;
union quant arr;
};
int main(void) {
struct member* ptr;
ptr = (struct member *)malloc(sizeof(struct member));
ptr->total = 2;
int type = 0;
if(!type) {
ptr->arr.df = (struct dfp*)malloc(ptr->total*sizeof(struct dfp));
for(int i=0;i<2;i++){
ptr->arr.df->fp[i] = 10;
}
}
else {
ptr->arr.af = (struct affine*)malloc(ptr->total*sizeof(struct affine));
for(int i=0;i<2;i++){
ptr->arr.af->scale[i] = 10;
ptr->arr.af->zp[i] = 20;
}
}
if(!type) {
free(ptr->arr.df);
}
else {
free(ptr->arr.af);
}
free(ptr);
}
Correct the struct definition as below:
struct dfp {
int fp;
};
struct affine{
int scale;
int zp;
};

C, Invalid write with valgrind and void* variable

I want to assign a variable void* to an attribut void* from a structure.
My struct :
struct data{
int n;
void * cl;
}typedef data;
Then, I have this function :
void f(void *cl, int n){
struct data *data = malloc(sizeof(data));
data->cl = cl; //"Invalid write of size 8" from valgrind
data->n = n;
}
EDIT : "void *cl" is null, I don't know why (but not data)
And I call it like this :
f(args_f(2), 1);
About args_f :
struct st_args * args_f(int n)
{
struct st_args *args = malloc(sizeof(struct st_args));
if (args == NULL)
return NULL;
args->n = n;
return args;
}
The struct st_args :
struct st_args{
int n;
}typedef st_args;
Inside my function f, when I try the assignement "data->cl = cl;", valgrind says "Invalid write of size 8" on this line. why is that ?
I see a problem here: struct st_args *args is local, and you have returned it, without allocating proper memory.
struct data *data = malloc(sizeof(data));
At this instance, data is a pointer, and malloc would have allocated 4 (or 8) bytes of memory. It should have been,
struct data *data = malloc(sizeof(struct data));
This would allocate (if available) the required memory and segfault would go away.
Additionally, you should check if data is NULL after malloc, if yes then handle the error the way you have done in args_f function.
This is the exact reason why we should be avoiding variable naming convention where user-defined data types and variable names can be same.
For that matter, when I have a typedef, I typically have _t suffix to it to avoid any confusion.
For example,
This
struct data{
int n;
void * cl;
}typedef data;
would be something like this in my code
typedef struct stData {
int32_t i_N;
void *p_cl;
} data_t;

Unfamiliar C systax - declaring variables after a struct

#include "stdio.h"
void main( )
{
struct {
char initial;
int age;
int grade;
} kids[12], *point, extra;
I am following the tutorial from here http://www.gatesit.org/gitdownloads/C&DS.pdf page 813-22 and I don't quite understand what kids[12], *point, extra; means. From what I know you can initialize variables of the struct after the definition of it like that but why is there an array size 12, a pointer and extra?
Here is the code following it.
int index;
for (index = 0; index < 12; index++)
{
point = kids + index;
point->initial = 'A' + index;
point->age = 16;
point->grade = 84;
}
kids[3].age = kids[5].age = 17;
kids[2].grade = kids[6].grade = 92;
kids[4].grade = 57;
for (index = 0; index < 12; index++)
{
point = kids + index;
printf("%c is %d years old and got a grade of %d\n",
(*point).initial, kids[index].age, point->grade);
}
extra = kids[2]; /* Structure assignment */
extra = *point; /* Structure assignment */
}
struct mystruct {
char initial;
int age;
int grade;
} kids[12], *point, extra;
is equivalent to:
struct mystruct {
char initial;
int age;
int grade;
};
struct mystruct kids[12];
struct mystruct *point;
struct mystruct extra;
In your particular case, your struct doesn't have a tag name, so you actually can't create any instances of it afterwards - this is the only way you could do it, since it's unnamed.
Since here the struct is being defined inside a function, and its definition will only be available in that function, then it's likely you won't need to define any more instances of it, so there's no disadvantage of not having a name. On the other hand, other than having one less name in the tag namespace (and therefore avoiding the possibility of hiding a tag name at file scope), there's no particular advantage to it, either.
struct {
char initial;
int age;
int grade;
} kids[12], *point, extra;
This struct is unnamed.
This creates an array of 12 of this struct, named kids, a pointer to this type of struct named point, and another one of these structs named extra.
For a one-off structure, used only in a few limited places, this is acceptable. In a larger usage case, I would consider this kind of "sloppy", and would prefer to see something like this:
typedef struct {
char initial;
int age;
int grade;
} student_t;
int main() {
student_t kids[12]; // 12 students in the class
student_t* pStudent; // A pointer to a student_t
student_t extra; // The new kid
}
This basically defined an array of 12 elements of the defined struct kids[12], another variable that is a single pointer to the defined struct *point and finally a single instance of the struct extra.
Since the struct doesn't have a name, I suppose you'd have to define all of them at once next to the struct definition.
Equivalently, it could've been something like this:
struct kid {
char initial;
int age;
int grade;
};
struct kid kids[12];
struct kid *pointer;
struct kid extra;
You are declaring a 12 element array of the struct, a variable that is of the struct type, and a pointer to the struct. Then the code shows the different ways in which those types of variables can be used to access the inner pieces of the struct, and how the items can be assigned among each other.

access element of struct passed into a void* pointer

I'm working with a binary search tree data structure to sort a series of structs with the type definitions:
typedef struct {
char c;
int index;
} data_t;
typedef struct node node_t;
typedef node {
void *data;
node_t *left;
node_t *right;
}
The node_t typedef is from a library provided to me for this purpose, presumably with a void* pointer to ensure polymorphism. node will be passed into the function:
static void
*recursive_search_tree(node_t *root,
void *key, int cmp(void*,void*))
Within the recursive_search_tree function, I want to be able to modify the code to use the index element as a condition to find the match closest to the index of the linear pass over an array of characters, which would ultimately involve a data_t being passed into *key and key->index being accessed within the function.
The Question
Is it possible to access key->index where key is a void* pointing to a data_t struct, or would this only be possible if data_t was declared as the type for key? I have tried to do the latter, however even casting the pointer to an int doesn't seem to pass the compiler.
Sure it's possible, you'd cast key as type *data_t. (As long as that's really what key points to!)
key /* argument of type void* */
(data_t*)key /* cast as type data_t* */
((data_t*)key)->index /* dereferenced */
Here is a simple example:
#include <stdlib.h>
#include <stdio.h>
typedef struct {
char c;
int index;
} data_t;
typedef struct node {
void *data;
struct node *left;
struct node *right;
} node_t;
static int cmp(void *lhs, void *rhs)
{
return ((data_t *)lhs)->index - ((data_t *)rhs)->index;
}
int main(void)
{
data_t d0;
data_t d1;
d0.c = 'A';
d0.index = 1;
d1.c = 'B';
d1.index = 2;
printf("d0 < d1? %s\n", (cmp((void *)&d0, (void *)&d1) < 0 ? "yes" : "no"));
printf("d1 < d0? %s\n", (cmp((void *)&d1, (void *)&d0) < 0 ? "yes" : "no"));
return EXIT_SUCCESS;
}
This is type unsafe, as is any use of void. The use of void is generally because the intermediate is holding onto something it doesn't use for someone else's convenience.
This is a C function to let you hold whatever you want in a tree.
All it does is return whatever pointer you give it.
In your search function
int cmp(void* dt1, void* dt2)
{
data_t* data1 = (data_t*)dt1;
data_t* data2 = (data_t*)dt2;
/* Do what you need with data1 and data2 here */
}
Should let you do whatever you need. The problem you have is you need to cast your values inside the function. The parameters to cmp should exactly match the API for the library you are using, which says void* for the parameters.

Resources