convert list to struct - c

I'm trying to write a process table for my forks. I've got a global table and every process has to be written into this table.
I've got the struct
typedef struct {
int pid; /* Prozess ID */
char* name; /* Prozess Name (Programm) */
char* status; /* Status des Programms */
int check; /* bereits abgerufen? 1 - abgerufen, 0 - nicht abgerufen */
} Pstatus;
Listen:
typedef struct liste {
void *kopf;
struct liste *rest;
} *Liste;
listeKopf:
void* listeKopf(Liste l) {
if(l==NULL)
abbruch("listeKopf(listeLeer) undefiniert");
return l->kopf;
}
listeAnfuegen:
Liste listeAnfuegen(Liste l, void* element){
Liste neu=reserviere(sizeof (struct liste));
neu->kopf = element;
neu->rest = l;
return neu;
}
I'm writing my processes into the list using struct Pstatus. When I'm trying to read from my list I get the error: conversion to non-scalar type requested in line 284
my code is here:
http://pastebin.com/xEDvLTQk
Is somebody able to help me?

So Liste is a generic list that can hold references to anything via a void * pointer, right? And listeKopf returns that pointer.
According to your definition, Pstatus is a struct, not a pointer to struct, so you can't convert to it from void *. You also shouldn't be able to access its members with the -> operator, only with the dot . syntax.
(As a matter of personal taste, I prefer not to typedef pointer types, so that you can see whether a variable is a pointer or not by looking at the stars in the code.)

I looked at your code, basically on your line 284, you have this expression:
p = (Pstatus) listeKopf(temp);
the p is just the Pstatus struct variable and your listeKopf(temp) returns (void *kopf) which can not be assigned to a non-scaler variable( it should be assigned to a pointer).
you should change your code to look like this:
Pstatus *p
p = listeKopf(temp);
to avoid the error you are getting and also the cast to Pstatus is not needed as void * can be assigned to any pointer type.
Scalar types in C:
Arithmatic Types
Pointer Types
I hope it helps.

Related

How to access struct members from pointer [duplicate]

This question already has answers here:
How to access members through a void pointer
(4 answers)
Closed 3 years ago.
I'm having trouble accessing a struct's members when passed a void* pointer to that structure's base address. Can anyone offer a solution or explain the error to me? Right now I get the message "goroutines.c:142:31: error: request for member ‘qtail’ in something not a structure or union"
//Channel struct
struct channel{
int magicnumber;
int length;
int capacity;
struct gcb* qhead; //head of the queue
struct gcb* qtail; //tail of the queue
};
void *makeChannel(int dataLength, int capacity){
if( dataLength <= 0){
panic( "data length must be greater than zero" );
}
if( capacity < 0){
panic( "capacity must be non-negative" );
}
struct channel* ch = (struct channel* )malloc( dataLength * capacity );
ch->magicnumber = 0x1ca91ac3;
ch->capacity = capacity;
ch->length = 0;
return ch;
}
void sendChannel(void *channel, void *fetchAddress){
if( capChannel( channel ) == lenChannel( channel ) ){
(struct channel* )&channel->qtail->next = head;
}
}
It's not valid to de-reference a void* pointer. The de-referencing is basically a numerical off-set from the base-pointer. If the compiler does not know what type the pointer is, how can it know the offset amount, nor is it able to decide whether the member reference is actually valid.
In your function it is cast, It looks like there's a stray &.
void sendChannel(void *channel, void *fetchAddress)
{
struct channel *chan = (struct channel *)channel;
if( capChannel( chan ) == lenChannel( chan ) )
{
chan->qtail->next = head;
}
}
But your cast is not applied to anything. I prefer to make the cast explicit, by assigning it to a temporary local variable. I feel this makes the resultant code more readable, as it's not full of type-casts here & there.
The operator -> has lower precedence and so is evaluated first. channel is a void pointer so, when channel-> de-references it, you obtain a value of type void instead of the expected struct channel.
Add parenthesis around the cast and channel (or pass channel around as a struct channel * rather than void* to avoid repeated casting):
((struct channel *)channel)->qtail->next = head;

Add struct to struct array using void pointer to said array in C

Let's say I have the following struct and array of that struct:
struct Fileinfo {
int ascii[128]; //space to store counts for each ASCII character.
int lnlen; //the longest line’s length
int lnno; //the longest line’s line number.
char* filename; //the file corresponding to the struct.
};
struct Analysis fileinfo_space[8]; //space for info about 8 files
I want to have a function that will add a new struct to this array. It must take a void pointer to the position where to store the struct as an argument
int addentry(void* storagespace){
*(struct Fileinfo *)res = ??? //cast the pointer to struct pointer and put an empty struct there
(struct Fileinfo *)res->lnlen = 1; //change the lnlen value of the struct to 1
}
My questions are:
What goes in place of ??? I tried (Fileinfo){NULL,0,0,NULL} as per this Stackoverflow response. But I get `error: ‘Fileinfo’ undeclared (first use in this function)
How do I create a void pointer to the array? Is (void *)fileinfo_space correct?
I am required to use void * as the argument for the function for this assignment. It's not up to me.
Let's say you have some memory block passed as storagespace void pointer:
You have to define a constant to be able to initialize (unless you're using c++11), let's call it init. BTW your assignment value is wrong: first member is an array of int. You cannot pass NULL to it. Just zero-fill it like show below.
Then cast your void pointer into a pointer on your struct, then initialize by copying the init struct, modify at will...
int addentry(void* storagespace){
static const struct Fileinfo init = {{0},0,0,NULL};
struct Fileinfo *fi = (struct Fileinfo *)storagespace;
*fi = init; //cast the pointer to struct pointer and put an empty struct there
fi->lnlen = 1; //change the lnlen value of the struct to 1
}

Understanding pointer structs in C

I am trying to understand an assignment I have before I have to take a final. I am trying to understand what exactly I am declaring.
So in a given file the typedef struct's are declared as so:
(Struct Declaration)
/** The following two structs must be defined in your <gamename>.c file **/
typedef struct game_position_t *game_position;
/* move struct must code enough information to reverse the move, given the resulting position */
typedef struct move_t *move;
I have then built the structs out as so (yes this has to be separated just because it is interfaced programming):
(Struct Definition)
/** The following two structs must be defined in your <gamename>.c file **/
struct game_position_t {
int mathy;
int numrows;
int *sizes;
};
/* move struct must code enough information to reverse the move, given the resulting position */
struct move_t {
int rownum;
int move_size;
};
Then an example of a functions and declaration of game_position for example is:
(Example Function)
/* return the starting position, NULL if error */
game_position starting_position(int me_first, int argc, char **argv) {
if (argc < 3) {
printf("\n\nToo few arguments, see help below\n\n");
game_help(argv[0]);
return NULL;
}
int mathy;
if (strcmp(argv[2],"search")==0)
mathy = 0;
else if (strcmp(argv[2],"mathy")==0)
mathy = 1;
else {
printf("\n\nSecond argument must be \"search\" or \"mathy\", see help below\n\n");
game_help(argv[0]);
return NULL;
}
int play_default = (argc==3);
if (play_default) printf("\n\nOK, we will play the default game of 7 5 3 1\n\n");
int defaultgame[4] = {7,5,3,1};
game_position result = malloc(sizeof(struct game_position_t)*1);
result->mathy = mathy;
if (result) {
result->numrows = (play_default ? 4 : argc-3);
result->sizes = malloc(sizeof(int)*(result->numrows));
int row;
for (row=0; row<(result->numrows); row++)
(result->sizes)[row] = (play_default ? defaultgame[row] : strlen(argv[row+2]));
}
return result;
}
So my main misunderstanding is when using a struct declaration in this manner, specifically putting the * before the name like this, typedef struct move_t *move;. Is that previous line saying move it a struct pointer or dereferencing move? Continuing from that. When defining them I just use the struct name such as struct move_t. I don't fully understand how they are linking together and in what matter. Then inside the function I just declare game_position, but still need to use a derefencer, 'p->`, to access it fields. So if someone could explain to me when these struct variables are points to structs and when they are the actual struct.
An example of my misunderstanding is that in the Example Function after result was declared. I first thought to use the . operator to access and set it's fields. I then changed it due to compiler errors, but now I want to understand my misunderstanding. And why did I I have to malloc game_position_t and not game_position?
typedef defines a type, so typedef struct move_t *move defines a new type named move, which is a pointer type, pointing to struct move_t. So after this if you define a variable with move ptr, ptr will have a pointer type so that you should use the syntax of accessing members through a pointer. When allocating memory for it, of course you have to specify the exact size of the structure other than the size of a pointer, that's sizeof(struct move_t)

error accessing/using void pointers in c

So I have this Linked List print function that is giving me the error:
error: invalid use of void expression
Here's the line that causes this error:
printf("[%d] -> ", *(link->pointer)); /*note: i tried to cast it to (int) but still same error. */
Here's my struct for the link; very straight forward:
typedef struct DLLNode {
void * pointer;
struct DLLNode *next;
struct DLLNode *previous;
} DLLNode;
I'm using my prepend function as so:
...
int j = 2;
prepend(&j, list);
...
so that it uses the pointer to variable two as the value the struct stores in new DLLNode as the pointer.
Could someone tell me why this is happening and what it means? Thanks for your time.
I suppose you are trying to print the value that link->pointer points to.
printf("[%d] -> ", var) expects to see either an integer in its argument list or something that can be converted to it (for example, a char).
link->pointer is of type void * and after dereferencing, it looks like a void type variable. Thus, compiler can't convert *(link->pointer) to int type. To tell it that you actually keep an integer value behind that void * pointer you need to explicitly convert link->pointer to a int * type, as Kaz pointed out in the comments and only then dereference it. I hope the following code demonstrates this more clearly:
DLLNode *list;
// initialization and other stuff
void *p = list->pointer;
int *p_i;
p_i = (int*)p; // explicit cast to int*
// print the integer value pointed to by the list->pointer
printf("[%d] -> ", *p_i);

incompatible pointer type - why?

I am trying to understand the inner workings of queue (3) macros in Freebsd. I had asked a previous question about the same topic and this is a follow up question to it.
I am trying to define a function to insert an element into the queue. queue (3) provides the macro STAILQ_INSERT_HEAD which needs a pointer to the head of the queue, type of the items in queue and the item to be inserted. My problem is that I am getting
stailq.c:31: warning: passing argument 1 of 'addelement' from incompatible pointer type
error when I try to pass the address of head to the function. The full source code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <sys/queue.h>
struct stailq_entry {
int value;
STAILQ_ENTRY(stailq_entry) entries;
};
STAILQ_HEAD(stailhead, stailq_entry);
int addelement(struct stailhead *h1, int e){
struct stailq_entry *n1;
n1 = malloc(sizeof(struct stailq_entry));
n1->value = e;
STAILQ_INSERT_HEAD(h1, n1, entries);
return (0);
}
int main(void)
{
STAILQ_HEAD(stailhead, stailq_entry) head = STAILQ_HEAD_INITIALIZER(head);
struct stailq_entry *n1;
unsigned i;
STAILQ_INIT(&head); /* Initialize the queue. */
for (i=0;i<10;i++){
addelement(&head, i);
}
n1 = NULL;
while (!STAILQ_EMPTY(&head)) {
n1 = STAILQ_LAST(&head, stailq_entry, entries);
STAILQ_REMOVE(&head, n1, stailq_entry, entries);
printf ("n2: %d\n", n1->value);
free(n1);
}
return (0);
}
As far as I can tell, head is of type struct stailhead and the addelement function also expects a pointer to struct stailhead.
STAILQ_HEAD(stailhead, stailq_entry); expands to:
struct stailhead {
struct stailq_entry *stqh_first;
struct stailq_entry **stqh_last;
};
What am I missing here?
Thanks.
You just need to convert the first line in your main function from
STAILQ_HEAD(stailhead, stailq_entry) head = STAILQ_HEAD_INITIALIZER(head);
to
struct stailhead head = STAILQ_HEAD_INITIALIZER(head);
What's happening is that STAILQ_HEAD is a macro that defines a new type, a struct that is your data structure with the name of the first parameter with an entry type of the second parameter.
You're only supposed to call STAILQ_HEAD once to define the type of the struct - then you use that typename from thereon to create new data structures of this type.
What you did in your code sample is simple: you defined a struct named stailhead twice - once in the global scope and once in the scope of your main function. You were then passing a pointer to the local stailhead to a function that accepted the global type with the same name.
Even though both structs are identical, they're in two different storage scopes and the compiler treats them as distinct types. It's warning you that you're converting from type main::stailhead to type global::stailhead (note that I have just made up this notation, I do not believe it is canon).
You only need to define stailhead by calling the STAILQ_HEAD macro just once at the top of the file where you already did, and from thereon use struct stailhead to define an object of this type.

Resources