C - emulate 'mutable' from C++ - c

I have a C structure like this:
struct my_struct {
int i;
double d;
struct expensive_type * t;
};
An instance of this structure is created and initialized as:
struct my_struct * my_new( int i , double d)
{
struct my_struct * s = malloc( sizeof * s);
s->i = i;
s->d = d;
s->t = NULL;
return s;
}
Calculating the struct expensive_type * t member is quite expensive, and might not be needed - it is therefor just initialized to NULL - and later calculated on demand:
const struct expensive_type * my_get_expensive( const struct my_struct * s)
{
if (!s->t)
s->t = my_expensive_alloc( s->i , s->d );
return s->t;
}
In C++ I would have used mutable on the struct expensive_type *member, is it possible to achieve something similar in C, i.e. casting away the const locally:
{
struct my_struct * mutable_s = (struct my_struct*) s;
mutable_s->t = ...;
  }
Or is removing const in the signature my only standard-compliant alternative?

You could(1) restructure your code and add a layer of indirection:
struct expensive; // Forward declaration, ignore
// One could also use a struct expensive * (a pointer) instead
// of this structure. IMO giving it a name is the better option.
struct expensive_handle {
struct expensive * target;
};
// Store the simple data members as usual, store a pointer to a
// handle (pointer) to the expensive ones
struct my_struct {
int simple;
struct expensive_handle * handle;
};
struct expensive {
int content; // whatever
};
Creating a my_struct must create the additional pointer/handle used for the indirection:
struct my_struct * new() {
struct my_struct * data = malloc(sizeof(*data));
// Error handling please
// Set simple data members
data->handle = malloc(sizeof(*(data->handle)));
// Error handling please
data->handle->target = NULL;
return data;
}
The target member (which will point to the expensive data once it is computed) is set to NULL initially.
Accessing (and thus possibly lazy computation of) the expensive data members is then possible even with a const qualified my_struct, because no data member of that my_struct is changed:
int get_expensive(struct my_struct const * ptr) {
if (ptr->handle->target == NULL) {
ptr->handle->target = malloc(sizeof(struct expensive));
// Error handling please
puts("A hell of a computation just happened!");
ptr->handle->target->content = 42; // WOO
}
return ptr->handle->target->content;
}
The only thing that changes is the data member of *(ptr->handle), a struct expensive_handle. Which is not const qualified (only the pointer to it named handle is).
Test (Live on ideone):
int main(void) {
struct my_struct * p = new();
printf("%d\n", get_expensive(p));
printf("%d\n", get_expensive(p));
}
(1) Whether this is reasonable or a complete waste of resources (both programmer and computation) cannot be decided from your dummy example, though.

Related

First element in a double pointer to struct is jiberrish

I am creating a simple array of structures in C, but the first structure is always jibberish. How do i fix this?
I have tried to set the first element of the double pointer to struct in many ways but it always fails.
This is my graph.h file:
#ifndef GRAPH_H
#define GRAPH_H
#include "set.h"
typedef struct urlNode * URLList;
typedef struct GraphRep * Graph;
struct urlNode {
int id;
char* URL_NAME;
URLList next; // link to next node
};
struct GraphRep {
int nV;
URLList * collections;
};
Graph newGraph(Set s);
int nameToId(Graph g, char *name);
void showGraph(Graph g);
#endif
And my newGraph(Set s) function looks like this:
Graph newGraph(Set s){
int size = nElems(s);
Graph new_graph = malloc(sizeof(struct GraphRep));
if (new_graph == NULL) {
printf("ERROR: COULDNT ALLOCATE GRAPH\n");
}
new_graph->nV = size;
char *name = getNextVal(s);
// THIS IS THE NODE TO BE ADDED TO THE GRAPH
URLList list_to_add = malloc(sizeof(struct urlNode));
list_to_add->URL_NAME = strdup(name);
list_to_add->id = 0;
list_to_add->next = NULL;
// HERE I ADD THE NODE TO THE GRAPH.
new_graph->collections[0] = list_to_add;
// PRINT OUT THE VALUES OF THE NEWLY ADDED NODE TO MAKE SURE IT WORKS
// THE URL_NAME IS PRINTED OUT FINE
// BUT THE ID IS JIBBERISH.
printf("%s\n", new_graph->collections[0]->URL_NAME);
printf("%d\n", new_graph->collections[0]->id);
if(new_graph->collections[0]->next != NULL) {
printf("%s\n", new_graph->collections[0]->next->URL_NAME);
printf("%d\n", new_graph->collections[0]->next->id);
}
printf("\n");
return new_graph;
}
I expect new_graph->collections[0]->id to be 0 but it keeps on giving me random ints.
Also even if the next for the newly declared pointer to struct is NULL, it still gives me a jibberish next value too.
Any help would be appreciated, thanks!
The data member collections of the object *new_graph is not initialized.
There is initialized only this data member
new_graph->nV = size;
So this statement
new_graph->collections[0] = list_to_add;
results in undefined behavior.
If you need an array of pointers of the type URLList you have to allocate the memory and its address assign to the pointer collections.
For example
new_graph->collections = malloc( new_graph->nV * sizeof( URLList ) );
And after that this statement
new_graph->collections[0] = list_to_add;
could be valid.
(I suppose that the data member nV corresponds to the number of elements in the dynamically allocated array though it may not be truth)
Pay attention to that as the string pointed to by the pointer name is not changed in the function then it is better to declare it like
const char *name = getNextVal(s);

Confused about updating a struct member in C

It has been a LONG time (25y) since I have done C and so I forget some things so please forgive the question.
Given that I have the following declarations:
typedef struct item {
int field;
} Item;
typedef struct data {
Item b;
} Data;
I have been trying to update the struct when its passed to a function and this doesn't work at all.
static void foo(Data *data) {
data->b.field = 3; // doesn't work, the struct remains unchanged.
}
static void test() {
Data v = {.b = {.field = 2}};
foo(&v);
}
However, if I alter the declaration slightly, use malloc to allocate it it works.
typedef struct data {
Item *b;
};
static void foo(struct data *data) {
data->b->field = 3; // works.
}
static void test() {
Data v = (struct data*) malloc(sizeof(Data));
Item i = (struct item*) malloc(sizeof(Item));
foo(v);
free(i);
free(v);
}
Can someone inform me why this is? Is it not possible to have struct members that are updatable as members? How could I make the first example work?
Thanks in advance.
Your first approach actually works (and I would have been surprised if it did not):
struct item {
int field;
};
struct data {
struct item b;
};
static void foo(struct data *data) {
data->b.field = 3;
}
static void test() {
struct data v = {.b = {.field = 2}};
printf("v.b.field before calling foo: %d\n", v.b.field);
foo(&v);
printf("v.b.field afterwards: %d\n", v.b.field);
}
int main() {
test();
}
Output:
v.b.field before calling foo: 2
v.b.field afterwards: 3
Probably your setting is a different one that than you've shown in the code. Mysterious things (i.e. undefined behaviour) often happens if you access an object after it's lifetime has ended. malloc often prevents such issues as it keeps an object alive until it is explicitly freed.
But in your case, there should not be any difference.
BTW: the typedef does not make sense, as you do not define an alias for the struct-type just declared. So
struct item {
int field;
};
is sufficient.

Cost of nested dereferencing negligible?

I have a family of large recursive functions that operate on trees. These trees are defined using "polymorphism", like so
struct foo {
enum abctype type;
union {
struct a ay;
struct b bee;
struct c cee;
}
};
where struct a... c are all nodes in the tree. Each node in the tree (i.e., any object of type struct a... c), points to an object of struct foo. For example:
struct a {
/* definitions */
/*...*/
struct foo *next;
};
Because of this, the struct dereferences end up getting very nested even though my functions aren't overreaching their purposes.
In this case, the nested dereferences are inevitable. It would be absurd to write cute little wrapper functions just to get rid of a ->. But, I've heard many programmers say that you shouldn't go past 3-4 dereferences or your "algorithm needs fixing".
So, what's the verdict? Does my code need fixing? are nested dereferences inefficient?
Edit:
Here's what my data structure looks like in more depth (they're not trees, as I have been told, unless linked list == tree):
struct a {
/* definitions */
/*...*/
struct foo *longitudinal;
};
struct b {
/* definitions */
/*...*/
struct foo *longitudinal;
struct b *transverse;
};
struct c {
/* definitions */
/*...*/
struct foo *longitudinal;
struct c *transverse;
};
Basically, the data structures are this way because the data they handle is organized this way (in my head). I just don't see a way to convert this to a binary tree.
A single pointer does not make a tree; it makes a list. Trees require at least two pointers. (You can find exceptions described at Wikipedia, but it is unlikely — though not impossible — that you're intending to use such an organization for your tree structure.)
I think your data organization is … well, if it is not wrong, then it is at least sub-optimal. You should almost certainly be using a structure more like:
struct tree
{
struct tree *left;
struct tree *right;
enum abctype type;
union {
struct a aye;
struct b bee;
struct c cee;
};
};
Where each of the single-letter structure types contains only the relevant (variant) data and not any tree-related pointers:
struct a
{
/* definitions */
/* …no struct tree *next; or anything similar… */
};
The tree traversal is now nice and uniform. Compare what used to be necessary with what is now necessary. Given the old struct foo *tp, your original code (probably) needed to do ghastly stuff like:
if (tp->type == TYPE_A)
process_next(tp->ay.next);
else if (tp->type == TYPE_B)
process_next(tp->bee.next);
else if (tp->type == TYPE_C)
process_next(tp->cee.next);
else
…report error…
(and similarly with a prev or left and right pointers, or whatever else you used to create an actual tree structure — though even as a list, this is more than a trifle messy).
With the revised scheme, given a struct tree *tp;, you now just use:
process_tree(tp->left);
process_data(tp);
process_tree(tp->right);
The data handling has to deal with the enumeration and accessing the appropriate portion of the anonymous union. This is much the same as before (except you don't need to futz with the tree structure pointers).
Working code
I observe that since you've not shown data for the structures a, b, and c, I've had to guess at what might be appropriate. If that sort of detail matters to you, it is important that you put that information in the question before people get to answer it. (That means, in part, don't go adding data fields to the structures now — you've already blown the opportunity to specify what is in them.)
This code works, more or less. The memory management doesn't have memory access errors, at least with the test data. The data isn't freed; that's an exercise for you to play with. Not all the error checking that should be there is there; that's another exercise for you. And the testing isn't all that comprehensive — guess what that means?
There could be some confusion about how your data structure is supposed to work. I've interpreted it as:
You can have a (longitudinal) list of items in arbitrary order, of type A, B or C. These are stored via struct foo, complete with the anonymous union.
Items of type B can have a transverse list of more type B items.
Items of type C can have a transverse list of more type C items.
Here's some code that works:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct a
{
char name[20];
};
struct b
{
double x;
double y;
struct b *transverse;
};
struct c
{
int height;
int width;
int depth;
struct c *transverse;
};
enum abctype { TYPE_A, TYPE_B, TYPE_C };
struct foo
{
struct foo *longitudinal;
enum abctype type;
union
{
struct a aye;
struct b bee;
struct c cee;
};
};
static struct foo *add_a_long(struct foo *head, const char *name)
{
struct foo *new_foo = malloc(sizeof(*new_foo));
if (new_foo != 0)
{
strncpy(new_foo->aye.name, name, sizeof(new_foo->aye.name)-1);
new_foo->aye.name[sizeof(new_foo->aye.name)-1] = '\0';
new_foo->type = TYPE_A;
new_foo->longitudinal = head;
}
return new_foo;
}
static struct foo *add_b_long(struct foo *head, double x, double y)
{
struct foo *new_foo = malloc(sizeof(*new_foo));
if (new_foo != 0)
{
new_foo->bee.x = x;
new_foo->bee.y = y;
new_foo->bee.transverse = 0;
new_foo->type = TYPE_B;
new_foo->longitudinal = head;
}
return new_foo;
}
static struct foo *add_c_long(struct foo *head, int height, int width, int depth)
{
struct foo *new_foo = malloc(sizeof(*new_foo));
if (new_foo != 0)
{
new_foo->cee.height = height;
new_foo->cee.width = width;
new_foo->cee.depth = depth;
new_foo->cee.transverse = 0;
new_foo->type = TYPE_C;
new_foo->longitudinal = head;
}
return new_foo;
}
static void add_b_trans(struct b *b, double x, double y)
{
struct b *new_b = malloc(sizeof(*new_b));
if (new_b != 0)
{
new_b->x = x;
new_b->y = y;
new_b->transverse = 0;
while (b->transverse != 0)
b = b->transverse;
b->transverse = new_b;
}
}
static void add_c_trans(struct c *c, int height, int width, int depth)
{
struct c *new_c = malloc(sizeof(*new_c));
if (new_c != 0)
{
new_c->height = height;
new_c->width = width;
new_c->depth = depth;
new_c->transverse = 0;
while (c->transverse != 0)
c = c->transverse;
c->transverse = new_c;
}
}
static void print_foo(const char *tag, const struct foo *head)
{
printf("\n%s:\n", tag);
while (head != 0)
{
switch (head->type)
{
case TYPE_A:
printf("A: %s\n", head->aye.name);
break;
case TYPE_B:
{
const struct b *bp = &head->bee;
printf("B-main: (%f,%f)\n", bp->x, bp->y);
while ((bp = bp->transverse) != 0)
printf("B-trans: (%f,%f)\n", bp->x, bp->y);
}
break;
case TYPE_C:
{
const struct c *cp = &head->cee;
printf("C-main: (%d,%d,%d)\n", cp->height, cp->width, cp->depth);
while ((cp = cp->transverse) != 0)
printf("C-trans: (%d,%d,%d)\n", cp->height, cp->width, cp->depth);
}
break;
}
head = head->longitudinal;
}
}
int main(void)
{
struct foo *head = 0;
head = add_a_long(head, "Caterpillar");
print_foo("1 item", head);
head = add_a_long(head, "Ununtrium");
print_foo("2 items", head);
head = add_b_long(head, 1.00000, 1.00000);
head = add_b_long(head, 3.14159, 2.78128);
print_foo("4 items", head);
assert(head->type == TYPE_B);
add_b_trans(&head->bee, 1.2345, 2.3456);
add_b_trans(&head->bee, 9.8765, 6.5432);
print_foo("4 items, 2 transverse B", head);
head = add_a_long(head, "Ununpentium");
head = add_c_long(head, 3, 4, 5);
head = add_c_long(head, 5, 12, 13);
print_foo("6 items", head);
assert(head->type == TYPE_C);
add_c_trans(&head->cee, 7, 20, 27);
add_c_trans(&head->cee, 9, 35, 36);
head = add_a_long(head, "Ununseptium");
head = add_a_long(head, "Ununoctium");
print_foo("Final", head);
return 0;
}
And this is the sample output I get:
1 item:
A: Caterpillar
2 items:
A: Ununtrium
A: Caterpillar
4 items:
B-main: (3.141590,2.781280)
B-main: (1.000000,1.000000)
A: Ununtrium
A: Caterpillar
4 items, 2 transverse B:
B-main: (3.141590,2.781280)
B-trans: (1.234500,2.345600)
B-trans: (9.876500,6.543200)
B-main: (1.000000,1.000000)
A: Ununtrium
A: Caterpillar
6 items:
C-main: (5,12,13)
C-main: (3,4,5)
A: Ununpentium
B-main: (3.141590,2.781280)
B-trans: (1.234500,2.345600)
B-trans: (9.876500,6.543200)
B-main: (1.000000,1.000000)
A: Ununtrium
A: Caterpillar
Final:
A: Ununoctium
A: Ununseptium
C-main: (5,12,13)
C-trans: (7,20,27)
C-trans: (9,35,36)
C-main: (3,4,5)
A: Ununpentium
B-main: (3.141590,2.781280)
B-trans: (1.234500,2.345600)
B-trans: (9.876500,6.543200)
B-main: (1.000000,1.000000)
A: Ununtrium
A: Caterpillar
The canonical way to go about this is to really use the structs like derived classes. I. e.:
struct base {
enum abctype type;
};
struct a {
struct base super;
//whatever other data members `a` happens to have
};
With this approach, you write functions taking a struct base*, which is subsequently cast to one of the subclasses once. Further manipulation of the object uses the derived class pointer with only a single ->.
Btw: If you include a function pointer within struct base, you can directly call the derived class's function (no switch required). Bonus points for grouping the function pointers in a struct of their own (instanciated as global tables), with a single pointer in struct base pointing to the correct function table. That would very, very close to what C++ does under the hood...
struct base_vtable {
void (*foo)(int, double);
int (*bar)(struct base*);
int (*baz)();
};
struct a_vtable {
struct base_vtable super;
double (*bim)();
dobule (*bam)();
};
struct base {
struct base_vtable vtable;
};
struct a {
struct base super;
//whatever
};
And then, somewhere in a .c file:
static struct a_vtable g_a_vtable = {
.super.foo = &a_foo,
.super.bar = &a_bar,
.super.baz = &a_baz,
.bim = a_bim,
.bam = a_bam
};
struct a* a_create(...) {
struct a* me = malloc(sizeof(*me));
me->super->vtable = g_a_vtable;
//further initialization
};

how to access the struct?

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

Allocate struct from function in C

I'm having issues writing a function that allocates a struct in C. Ideally, I want to have the function fill the fields of the struct with parameters passed into it.
I have defined the struct in my header file like so:
typedef struct {
char name[NAME_SIZE]; //Employee name
int birthyear; //Employee birthyear
int startyear; //Employee start year
} Employee;
And this is what I have for my function currently:
void make_employee(char _name, int birth_year, int start_year) {
Employee _name = {_name,birth_year,start_year}; //allocates struct with name
} /* end make_employee function */
Any advice on how to accomplish this?
The problem with your current code is that the struct your creating is created on the stack and will be cleaned up as soon as the function returns.
struct foo
{
int a;
int b;
};
struct foo* create_foo( int a, int b )
{
struct foo* newFoo = (struct foo*)malloc( sizeof( struct foo ) );
if( newFoo )
{
newFoo->a = a;
newFoo->b = b;
}
return newFoo;
}
This will get you a heap allocated object. Of course, you'll need a function to free that memory or this is a memory leak.
void destroy_foo( struct foo* obj )
{
if( obj )
free( obj );
}
void print_foo( struct foo* obj )
{
if( obj )
{
printf("foo->a = %d\n",obj->a);
printf("foo->b = %d\n",obj->b);
}
}
(btw, this style gets you part of the way toward an "object oriented" C. Add some function pointers to the struct (to get polymorphic behavior) and you have something interesting; though I'd argue for C++ at that point.)
You have to return a pointer allocated via malloc:
Employee* new_employee(char *_name, int birth_year, int start_year) {
struct Employee* ret = (struct Employee*)malloc(sizeof(struct Employee));
ret->name = _name;
ret->birth_year = birth_year;
ret->start_year = start_year;
return ret;
}
two more things: (1) you should make the struct definition of name a char* instead of char[NAME_SIZE]. Allocating a char array makes the struct much bigger and less flexible. All you really need is a char* anyway. And (2) change the function definition to char*.
Why does the make Employee return void? You need to return the Employee from the make_employee function!
Are you having trouble with the compiler complaining about the x = {a,...} syntax? Write it the long way then: Emp e; e.field1 = a; ...
Are you having weird overwriting / bogus numbers problems? If you allocate a struct in the function it will become invalid (and prone to being overwriten) as soon as the function returns! To go around this you either have to:
Return a copy of the struct (this is OK for small structs):
Employee make_emp(int a){
Emp emp; //Allocate temporary struct
emp.filed1 = a; //Initialize fields;
return emp; // Return a copy
}
Allocate the struct in the heap instead and deal with it through references (ie.: pointers) instead:
Employee* make_emp(int a){
Emp* emp = malloc(sizeof(Emp)); //Allocate the struct on the heap
//And get a reference to it
emp->filed1 = a; //Initialize it
return emp; //Return the reference
}
Don't forget to free() the Employee after you are done with it in this case!
Employee * make_employee(char *_name, int birth_year, int start_year)
{
Employee *employee;
if (employee = (struct Employee *)memalloc(sizeof(Employee)) == NULL)
{
return NULL;
}
else
{
strcpy(&(employee->name), _name);
employee->birthyear = birth_year;
employee->startyear = start_year;
return employee;
}
}

Resources