C struct question - c

I have a interface documented like this:
typedef struct Tree {
int a;
void* (*Something)(struct Tree* pTree, int size);
};
Then as I understand I need to create instance of it, and use Something method to put the value for 'size'.
So I do
struct Tree *iTree = malloc(sizeof(struct Tree));
iTree->Something(iTree, 128);
But it keeps failing to initialize. Am I doing this right?
Howcome the first member of the Something method is pointer to the very same struct?
Can anyone explain please?
Thanks

You have to set Something to something since it is only a function pointer and not a function. The struct you created with malloc just contains garbage and struct fields need to be set before it is useful.
struct Tree *iTree = malloc(sizeof(struct Tree));
iTree->a = 10; //<-- Not necessary to work but you should set the values.
iTree->Something = SomeFunctionMatchingSomethingSignature;
iTree->Something(iTree, 128);
Update
#include <stdlib.h>
#include <stdio.h>
struct Tree {
int a;
//This is a function pointer
void* (*Something)(struct Tree* pTree, int size);
};
//This is a function that matches Something signature
void * doSomething(struct Tree *pTree, int size)
{
printf("Doing Something: %d\n", size);
return NULL;
}
void someMethod()
{
//Code to create a Tree
struct Tree *iTree = malloc(sizeof(struct Tree));
iTree->Something = doSomething;
iTree->Something(iTree, 128);
free(iTree);
}

This is a poor man's virtual function. The initial parameter is roughly equivalent to C++'s this pointer in a member function. And you must manually set the function pointers before calling them, whereas C++ virtual functions are set up by the compiler.

The member Tree::Something is never initialized. You allocate space for a Tree, but allocation is different from initialization, and your allocated Tree contains only unmeaningful bits.

Related

Why is this linked-list initialization not working?

I'm trying to initialize (or create) a linked-list with an empty node pointing to NULL, but it's returning an error and I don't know why. Can somebody help me?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
int times;
char name[100];
char number[100];
struct node* next;
};
typedef struct node* node;
void mklist(node* n) {
(*n)->times = 0;
strcpy((*n)->name, "null");
strcpy((*n)->number, "null");
(*n)->next = (node)NULL;
}
int main(void) {
node n;
mklist(&n);
return 0;
}
So node is actually a pointer to a struct node, very confusing
typedef struct node* node;
In main() you declare a pointer and pass a pointer to a pointer to mklist()
node n;
mklist(&n);
In mklist(), n is actually a pointer to a pointer to the struct, so derefencing it, you get a pointer to a struct
void mklist(node* n){
(*n)->times=0;
but nowhere in your code have you allocated memory for an actual struct.
The most straightforward fix with the way your code is currently is to add a malloc()
void mklist(node* n) {
*n = malloc(sizeof(*(*n)));
// check for malloc() failure
(*n)->times = 0;
strcpy((*n)->name, "null");
strcpy((*n)->number, "null");
(*n)->next = (node)NULL;
}
You can do this easily in the global scope:
// nil = &nilObj, which means nil->next == nil.
//
// This way, there's no checking for both 'nil' and 'NULL'!
//
// As a consequence of this last point, you can make passing 'NULL'
// to most list functions invalid: it just means the user didn't
// use mklist() on every list they needed to manually work with.
static struct node nilObj = { 0, "null", "null", &nilObj };
node nil = &nilObj;
void mklist(node *n)
{
*n = nil;
}
As Stephen Docy mentioned, using typedef T *Tname; is generally a bad idea as it hides the fact that you're using a pointer, which can be confusing when you use Tname *n as (*n)->foo (I'd expect to use it as n->foo honestly). Some APIs do this, but they do it in a way that expresses that the variable is a pointer to an object rather than an object: instead of Node, something like NodeRef or NodePtr is used, signifying in the name that it's a pointer to a node, not a node. Apple's Core Foundation API uses names like this (e.g. CFStringRef). I highly suggest adopting a convention similar to this henceforth. The above code I posted might then look something like this:
static struct node nilObj = { 0, "null", "null", &nilObj };
nodeRef nil = &nilObj;
void mklist(nodeRef *n)
{
*n = nil;
}

C Programming EXC_BAD_ACCESS (code:1 ,address=0x0) Error

Hi guys I'm learning C programming. I wanted to write some codes for learning linked list topic but there is a problem. This code about creating linked list with 5 nodes, writing something into 3rd node, printing them to console.
Here is all of my codes:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
struct node{
char *data;
struct node *next;
};
typedef struct node node;
node *root;
void nodeAdd(node *n, int x)
{
node *iter;
iter=root;
for(int i=0;i<x;i++)
{
iter->next = (node*)malloc(sizeof(node));
iter->next->data="0";
iter->next->next=NULL;
iter=iter->next;
printf("Node created.\n");
}
}
void nodeWrite(node *n,char *string,int x)
{
node *temp;
temp=root;
for(int k=0;k<x;k++)
{
temp=temp->next;
}
strcpy(temp->data,string); //HERE IS ERROR
printf("\n");
printf("%s \n",temp->data);
printf("Node writed.");
}
void nodePrint(node *n)
{
while(root->next!=NULL)
printf("%s\n",root->data);
root=root->next;
}
int main(int argc, const char * argv[])
{
root = (node*)malloc(sizeof(node));
nodeAdd(root,5);
nodeWrite(root,"WTF", 3);
nodePrint(root);
return 0;
}
data is an unintialized pointer variable. Initialize with the address of a valid memory that you allocate. That will solve the problem. Now you have udnefined behavior.
What you can possibly do is
Use char array instead of using pointer.
Allocate dynamically the memory.
In case of 1.
struct node{
char data[MAXSTRINGLEN];
struct node *next;
};
In case of 2:
Initially make the pointers point to NULL. So now you can allocate to it like this
temp->data = malloc(sizeof *temp->data*MAXSTRINGLEN);
if( temp->data == NULL)
{
fprintf(stderr,"Error in malloc");
exit(1);
}
Just one point, free the allocated memory when you are done working with it.
Use of the global variable here is not really required here. You can always pass return pointers from memory and assign it to the struct node*. Or yes you can use double pointers. Use of global variable is not needed here.
Clean up code, that are redundant and not required. That makes things readable and less confusing.
The program initially is designed incorrectly and has undefined behavior..
For example the data member data of the node root was not initialized. So its output in the function nodePrint results in undefined behavior. Moreover the function itself is incorrect.
Neither function uses its parameter node *n.
In this statement
strcpy(temp->data,string);
there is an attempt to change the string literal pointed to by the data member temp->data provided that the data member was initialized (as it was pointed above the data member is not initialized for the node root). You may not change a string literal. Any attempt to modify a string literal leads to undefined behavior.
There is no need to declare the node root as a global variable.
Parameters of the function main are not used in the program. So the function should be declared like
int main( void )

Generic programming in C

I am writing a generic linked list implementation in pure C.
struct Node {
void *value;
struct Node *next;
};
struct LinkedList {
struct Node *start;
struct Node *end;
};
void LinkedList_new(struct LinkedList* llist) {
llist->start = 0;
llist->end = 0;
return;
}
void addNode( struct LinkedList *ll, void *_value ) {
if ( NULL == ll->start ) {
ll->start = (struct Node *) malloc( sizeof(struct Node) );
ll->end = ll->start;
} else {
ll->end->next = (struct Node *) malloc( sizeof(struct Node) );
ll->end = ll->end->next;
}
ll->end->value = _value;
return;
};
This all works great. My problem is when I get to printing value to the screen. I can't seem to find a generic implementation for printing.
Is there a way to determine the TYPE allocated to void *? (And then just do conversion using a switch statement)
void printFunc(int aInt) {
char str[15];
sprintf(str, "%d", aInt);
printf(str);
}
This is an implementation that works for int. Worst case I was thinking was writing a different function for each TYPE. Is this really my only route when using void *?
Is there a better way to do this?
No, there's no way to figure that out from the pointer alone. That would require type information to be stored at some well-defined location in all run-time structures, which is simply not how C uses the machine.
The common solution is for the user of the datatype to provide the print function that the application needs, since the application will know the type of data being stored. That is, there is usually an iteration function that takes a function pointer, calling the user's function (which might print the element) on each element of the list.
Here's how such a function could look:
void LinkedList_foreach(const LinkedList *start,
bool (*func)(void *element, void *data), void *data);
The above should call func() for each element of the list, passing it the element's data and the additional user-supplied data pointer which can be used by the caller to maintain state for the traversal. The callback func() should return false to stop the iteration, true to keep going.
To print an integer, assuming the integers are stored in the pointers, you could have:
static bool print_int(void *element, void *data)
{
printf("%d\n", (int) element);
return true;
}
Also, please don't cast the return value of malloc() in C.

Error while generating an array of pointer

Trying to implement below code for some assignment but getting an error for malloc array generation "[Error] conflicting types for 'stack'" Any Help ??
Thanks in Advance.
#include<stdio.h>
#include<stdlib.h>
struct treenode
{
char info;
struct treenode *firstchild;
struct treenode *next;
int flag;
};
typedef struct treenode *NODEPTR;
NODEPTR *stack;
// Trying to create array here
stack=(NODEPTR*)malloc(sizeof(NODEPTR)*20);
int main()
{
printf("YO\n");
return 0;
}
EDIT :
I can't move it to main , as i have to access the stack globally in different functions.
because Stack array gets destroyed when it go to another function.
check here http://ideone.com/5wpZsp ,
When i give static declaration globally it works smoothly, here : http://ideone.com/3vx9fz
You can not call assignment operations at global scope. Try malloc operation in main() instead.
And the type of stack is not a pointer but pointer to pointer. Are you sure about it's declaration ?
Move your initialization of stack to inside of the main method.
EDIT An example showing how the malloc data can persist to other function calls even though malloc is called inside of main.
#include<stdio.h>
#include<stdlib.h>
struct treenode
{
char info;
struct treenode *firstchild;
struct treenode *next;
int flag;
};
typedef struct treenode *NODEPTR;
NODEPTR *stack;
void test_stack()
{
printf("%p\n", stack);
printf("%d\n", stack[19]->flag);
}
int main()
{
// Trying to create array here
stack=(NODEPTR*)malloc(sizeof(NODEPTR)*20);
stack[19] = (NODEPTR*)malloc(sizeof(struct treenode));
stack[19]->flag = 42;
test_stack();
return 0;
}
Step 1: Move the declaration of stack inside main. There's no reason it should be declared globally:
int main( void )
{
NODEPTR *stack;
...
Step 2: Move the malloc call inside main (you cannot perform an assignment or a function call outside of a function).
Step 3: Drop the cast; it's unnecessary1 and just adds visual clutter.
Step 4: Use sizeof *stack as opposed to sizeof (NODEPTR) in the argument to malloc:
stack = malloc( sizeof *stack * 20 );
The result is the same, but this is easier to read, and avoids maintenance headaches if you ever change the type of stack.
Step 5: free your stack when you're done. Yeah, for this program it doesn't matter, but it's a good habit to get into.
So after all this, your code should read:
int main( void )
{
NODEPTR *stack;
stack = malloc( sizeof *stack * 20 );
...
free( stack );
return 0;
}
Stylistic nit: Hiding pointer types behind typedefs is bad juju IME. Pointer semantics are important, and if the programmer is ever expected to dereference an object of type NODEPTR (either explicitly, as (*node).info, or implicitly, as node->info), then it's usually best to declare that object using pointer declaration syntax, something like
typedef struct treenode Node;
Node *node;
Node **stack;
...
stack[i]->next = node->next;
etc. so the person using your types knows exactly how many levels of indirection are involved and can write their code accordingly (multiple indirection is not hard). If the type is meant to be truly opaque and never directly dereferenced, but just passed around to an API that handles all that, then hiding the pointerness of that type is okay. Otherwise, leave it exposed.
I tend not to typedef struct types for a similar reason, but I suspect I'm an outlier in that regard.
Ahd who broke the code formatter?!
1 - In C, that is; in C++, the cast is required, but if you're writing C++, you should be using new instead of malloc anyway.
#include<stdio.h>
#include<stdlib.h>
struct treenode
{
char info;
struct treenode *firstchild;
struct treenode *next;
int flag;
};
typedef struct treenode *NODEPTR;
NODEPTR *stack;
int main()
{
stack=malloc(sizeof(NODEPTR)*20);
printf("YO\n");
return 0;
}
This will work.
allocate memory inside(malloc) your main.
There is no need to typecast out put of malloc. for further info see this post
EDIT :
In your comment you mentioned that memory will be destroyed when you move other function.
This is not true. Once you allocate memory using malloc it will not be destroyed until you call free().
So if you want to access the malloc'ed variable in other function pass the variable as argument to other function.
See this example program below
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
char *str;
void passMalloc(char **str);
int main()
{
str = malloc(100 * sizeof(char));
strcpy(str, "GoodMorning");
printf("\nMain before pass : %s\n", str);
passMalloc(&str);
printf("Main after pass : %s\n\n", str);
free(str);
return 0;
}
void passMalloc(char **str)
{
strcpy(*str, "GoodEvening");
printf("Function Def : %s\n", *str);
}

malloc array of structs in a struct

I have a struct called course and each course has multiple nodes (another struct 'node').
The number of nodes it has varies but I am given that number from a file that I am reading this information from, so that number sits in a variable.
So I need a malloc inside the struct. But I am confused. I know you can have arrays in structs but I don't know where to put the code that creates the malloc array since my struct is in my header file. Here's my code at the moment. I realize it looks wrong, I just don't know how I can fix it and where to initialize the malloc array.
struct course {
char identifier[2];
int num_nodes;
struct node *nodes;
nodes = (struct nodes*)malloc(num_nodes*sizeof(struct node));
};
struct node {
int number;
char type[2];
};
I want to be able to do something like:
struct node a_node;
struct course a_course;
a_course.nodes[0] = a_node;
etc...
I haven't used much C, this is the first time I've ever tried using dynamic arrays in C. My experience all comes from Java, and of course Java doesn't really use pointers in the same way as C so it's all a tad confusing for me.
So some help would be much appreciated, thanks a lot :)
The easiest approach is to create a function which initialises the struct:
void init_course(struct course* c, const char* id, int num_nodes)
{
strncpy(c->identifier, id, sizeof(c->identifier));
c->num_nodes = num_nodes;
c->nodes = calloc(num_nodes, sizeof(struct node));
}
For symmetry, you could also then define a destructor
void destroy_course(struct course* c)
{
free(c->nodes);
}
These would have usage like
struct course c;
init_course(&c, "AA", 5);
/* do stuff with c */
destroy_course(&c);
The purpose of malloc (or calloc - which I prefer to use for structs) is to dynamically allocate the memory at runtime. So, your struct should look like this, since it is an object definition:
struct course {
char identifier[2];
int num_nodes;
struct node *nodes;
};
Somewhere else in your program that uses the course struct, you will need to allocate memory (i) for any course objects you create and (ii) any node objects in that course.
e.g.
main()
{
// lets say 1 course
struct course *my_course;
my_course = calloc(1, sizeof(struct course));
// lets say 3 nodes in that course
struct node *my_nodes;
my_nodes = calloc(3, sizeof(struct node));
my_course.num_nodes = 3;
my_course.nodes = my_nodes;
//...
// clean up
free(my_nodes);
free(my_course);
}
Now, you are good. Make sure to free the memory before exiting.
it is also possible to direct allocate the structs in structs this way:
first declare your struct:
struct course {
char identifier[2];
int num_nodes;
struct node *nodes;
};
then in your program
main(){
int i;
struct course *c;
c = malloc(sizeof(struct course));
c->num_nodes = 3;
c->nodes = malloc(sizeof(struct node)*c->num_nodes);
for(i=0; i<c->num_nodes; i++)
c->nodes[i] = malloc(sizeof(struct node));
//and free them this way
for(i=0; i<c->num_nodes; i++)
free(c->nodes[i]);
free(c->nodes);
free(c);
}
or do it the way above what ever you like

Resources