user input in struct in C? - c

int a;
scanf("%d",a);
typedef struct mylist {
int info[a];
struct mylist *link;
} Node;
this is my very simple struct and variable 'a' that don't work.
The thing which I want my program to do is to read input from the user and insert the digit into the struct (the user can determine the size of the array), however, I don't know how to do it since I get an error:
"variably modified ‘info’ at file scope".
I want to know whether it is possible to do this in a simple way.

When you use scanf into an integer you must pass a pointer. You may want to check the documentation.
scanf("%d", &a);
As far as using a variable to allocate data, you can do it, but you will want to use malloc most likely after defining your structure as a type.

As pointed out by #David Hoelzer
scanf("%d",a);
should be
scanf("%d",&a);
If you are under C99 you can use flexible array members:
typedef struct mylist {
struct mylist *link;
int info[]; /* should be the last member */
} Node;
and then
Node *node = malloc(sizeof *node + (a * sizeof(int)));

You must have pointer to array of correct size or use flexible array. Here is how to use a pointer initializing it to point to storage of proper size.
struct mylist {
int *info; // or int info[] at the end of struct def if C99 is used
int info_size;
struct mylist *link;
};
int main(void)
{
int *array;
struct mylist m;
if (scanf("%d", &m.info_size) != 1)
{
perror("scanf failed");
exit(EXIT_FAILURE);
}
// ok
array = malloc(sizeof(int) * m.info_size);
if (array == NULL)
{
perror("malloc failed");
exit(EXIT_FAILURE);
}
// ok, commit changes
m.info = array;

Related

Cannot allocate dynamic array on C

Im trying to create a graph structure on C but I got some issues. First, Im getting 2 compilation errors:
main.c:18:19: error: member reference type 'node' is not a
pointer; did you mean to use '.'?
graph[index]->start = NULL;
~~~~~~~~~~~~^~
.
main.c:18:27: error: expression is not assignable
graph[index]->start = NULL;
~~~~~~~~~~~~~~~~~~~ ^
2 errors generated.
compiler exit status 1
I cannot figure out what Im doing wrong. I tried to create an array of nodes* but the compiler doesn't recognize it as a pointer for some reason. It's like malloc doesn't work. Also, I can't manage to acess edge* fields because it's like the array of nodes* is non-existent.
#include <stdio.h>
#include <stdlib.h>
#define maxNodes 4
typedef struct edge {
int target;
struct edge* next;
} edge;
typedef struct {
edge* start;
} node;
void initializeGraph(node* graph) {
graph = (node *) malloc(maxNodes * sizeof(node));
for(int index = 0; index < maxNodes; index++) {
graph[index]->start = NULL;
}
}
int main(void) {
node test;
initializeGraph(&test);
}
Im trying to initialize my structure. Any help is appreciated.
You have a large number of problems in your short example code. As to your error, that is covered by #dbush's answer and [...] serves as a dereference on your pointer making the '.' (dot) operator proper instead of the -> arrow operator.
Next, you cannot declare a node with static storage duration in main() and pass its address for allocation in your function. When you declare node test; all storage is already provided on the stack. You can't then pass that address to your function and allocate additional memory for that struct.
If you intend to have more than one node, then you can either declare an array with static storage duration in main(), or you must declare a pointer in main() and allocate in your function. To make that allocation visible in main(), as noted in my comment, you can either (1) make the return type node * and return a pointer to the allocated block for assignment in the caller, or (2) make the parameter node** and pass the address of your pointer as the parameter.
Putting that altogether and choosing option (1) above, you could do:
#include <stdio.h>
#include <stdlib.h>
#define maxNodes 4
typedef struct edge {
int target;
struct edge* next;
} edge;
typedef struct {
edge* start;
} node;
node *initializeGraph (void) {
node *graph = malloc(maxNodes * sizeof *graph);
if (!graph)
return NULL;
for (int index = 0; index < maxNodes; index++) {
graph[index].start = NULL;
}
return graph;
}
int main (void) {
node *test = initializeGraph();
if (!test)
fputs ("error: initialization failed.\n", stderr);
else
puts ("initialization succeeded");
}
Example Use/Output
$ ./bin/graphinit
initialization succeeded
Allocating For Each test[i].start
Before you can make use of any of the start pointers, you must allocate storage for a struct edge and assign the beginning address for that block of memory to each of your test[i].start pointers. You can do that in your same initializeGraph() function by allocating where you currently set the pointers NULL, e.g.
node *initializeGraph (void)
{
node *graph = malloc(maxNodes * sizeof *graph);
if (!graph)
return NULL;
for (int index = 0; index < maxNodes; index++) {
graph[index].start = malloc (sizeof *graph[index].start);
if (!graph[index].start)
return NULL;
}
return graph;
}
You can then assign a value to the target in each. Extending the earlier example, you could do:
int main (void) {
node *test = initializeGraph();
if (!test)
fputs ("error: initialization failed.\n", stderr);
else
puts ("initialization succeeded");
for (int i = 0; i < maxNodes; i++)
test[i].start->target = i;
puts ("targets filled");
}
Example Use/Output
$ ./bin/graphinit
initialization succeeded
targets filled
(don't forget to free the memory you allocate when it is no longer needed)
Look things over and let me know if you have further questions.
The array index operator [] implicitly dereferences a pointer. The syntax a[b] is exactly the same as *(a + b).
This means that graph[index] has type node, not node *. So use . instead of -> as the error message suggests.
graph[index].start = NULL;

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);

Why am i getting ' request for member ‘******’ in something not a structure or union'?

I'm getting the error for p->letter = 'A' and p->age = '9'. I don't know what is going wrong.
#include<stdio.h>
#include<stdlib.h>
struct player {
char letter;
int age;
};
typedef struct player *player_t;
int main (void)
{
player_t* p;
p = (player_t*)malloc(1 * sizeof(player_t));
if (p == NULL)
{
/* EDITED by #ahmedmasud removed original printf line for language */
printf("Unable to allocate\n");
return 1;
}
p->letter = 'A';
p->age = '9';
free(p);
return 0;
}
As many folks have pointed out you have a problem because in using typedef you went one step too far :-). Using typedef to recast types is meant for increasing clarity whereas the way you're using it decreases clarity.
Let me first show your example with the correct approach:
#include <stdio.h>
#include <stdlib.h>
struct player {
char letter;
int age;
};
/* typedef struct player *player_t; NOT NEEDED */
int main (void)
{
struct player *p;
p = malloc(sizeof(*p)); /* used *p for sizeof instead of struct player */
if (p == NULL)
{
fprintf(stderr, "Unable to allocate memory\n");
return 1;
}
p->letter = 'A';
p->age = '9';
free(p);
return 0;
}
When to use typedef foo_t bar_t
When it makes things clearer, e.g. stdint.h does this for integers. Say, you want a 32-bit unsigned int, you would use uint32_t which is appropriately typedef'd for various architectures to give you what you expect.
When NOT to use typedef struct foo foo_t
Pretty much all the time.
When it's OK to use typedef struct foo foo_t
Now for the reasons behind the changes, typedef struct foo foo_t is discouraged except when struct foo is opaque, typically when you are writing a C API where the structure is accessed through predefined access functions that have a longer life than internal structure.
Why use sizeof(*p) instead of sizeof(struct player) ?
In case, for some reason, you decide to change what *p is then all you have to do is change the declaration, and not worry that it's not going to get appropriately allocated.
This is an example of why you shouldn’t typedef a pointer.
player_t is a typedef for struct player *. You then define p as a player *, which means the full type of p is struct player **. The fact that you had a pointer hidden in a typedef ended up confusing you, and it can similarly confuse others who read your code.
Remove the pointer from the typedef and it will work as expected:
typedef struct player player_t;
You typedef
typedef struct player *player_t;
... so player_t is a type of pointer to struct player.
Then you define a variable:
player_t* p;
p is a pointer to pointer to struct player. Remove the *.
player_t* p; is not a pointer to struct player; it is a pointer to a pointer to struct player. Remove the * from the variable declaration and from the type cast before the call to malloc (you do not need that cast, anyway).
Change these two lines:
player_t* p;
p = (player_t*) malloc(1*sizeof(player_t));
into:
player_t p;
p = (player_t) malloc(1*sizeof(struct player));
p is of type player_t, which is already defined as a pointer to a player. No need for another * in its definition. Also, you need to allocate the size of the original struc, not the size of the pointer (sizeof(player_t) is the size in bytes of a pointer, not the size of the struct player).
Apart from what others pointed, Firstly typedef a pointer variable is not considered as good practice as hiding the * makes the code hard to read. Read Is it a good idea to typedef pointers?
Though if you want to typedef a pointer then do like below
typedef struct player {
char letter;
int age;
}player_t, *player_p; /* player_t is normal struct & player_p is pointer struct, here when someone see _p at the end of variable means it has * */
Next you need to allocate memory for player_p for e.g
player_p ptr = malloc(sizeof(struct player)); /* here don't take like "player_p *ptr" as player_p is already a pointer to struct */
if(ptr == NULL) {
/* error handling #TODO */
}
Later you can access structure member like
ptr->letter = 'A';
ptr->age = '9'; /* age is integer member, you may want to assign integer value directly like 57 instead of '9' */
And free the dynamically created memory by calling free().
free(ptr);
Sample code
typedef struct player {
char letter;
int age;
}player_t, *player_p;
int main(void) {
player_p ptr = malloc(sizeof(struct player));
if(ptr == NULL) {
/* error handling #TODO */
}
ptr->letter = 'A';
ptr->age = 50;
printf("%c .. %d \n",ptr->letter,ptr->age);
free(ptr);
return 0;
}

Trying to set a pointer to a struct

I have a function called SemCreate that takes a name an int and a pointer as parameters. I want the pointer to point to a new struct and I want to return an int, 0 if it went okay.
int P1_SemCreate(char *name, unsigned int value, P1_Semaphore *sem){
USLOSS_Console("Create a semaphore\n");
if(!verifyKernel()) {
//USLOSS_Console("ERROR: Not currently in Kernel mode\n");
USLOSS_Halt(1);
}
if(numSems>= P1_MAXSEM){
//USLOSS_Console("ERROR: MAX semaphore already exist\n");
return -2;
}
if(name == NULL){
return -3;
}
interruptsOff();
int i;
for (i = 0; i < P1_MAXSEM; i++) {
if (semTable[i].inUse == 0) {
semTable[i].value = value;
semTable[i].list = NULL;
semTable[i].name = malloc(sizeof(char));
strcpy(semTable[i].name, name);
semTable[i].inUse = 1;
semaphore *temp = NULL;
temp = malloc(sizeof(semaphore));
temp->value = value;
temp->list = NULL;
temp->name = malloc(sizeof(char));
strcpy(temp->name, name);
*sem = temp;
break;
}
}
numSems++;
interruptsOn();
return 0;
}
Right now the pointer is fine within the function but once I return the pointer is null
EDIT: The array semTable is an array of semaphores
typedef struct semaphore{
int value;
char * name;
struct node *list;
int checkPoint;
int inUse;
}semaphore;
typedef struct PCB {
USLOSS_Context context;
int (*startFunc)(void *); /* Starting function */
void *startArg; /* Arg to starting function */
int pid;
int status;
int killedStatus;
int state;
int priority;
char name[50];
int parentPID;
int numOfChild;
int blockFlag;
struct sempahore *blockSem;
char *stack;
struct node *children;
struct node *zombiList;
int cpuTime;
int startTime;
struct semaphore *childSem;
} PCB;
typedef struct node {
PCB *pcb;
struct node *next;
} Node;
Your question is not perfectly clear as to what you are trying to do. So, this answer addresses the following general topics in hopes they will assist:
1) Passing the address of a struct via a function, changing the values of the struct members, and accessing changed values in calling function. (It is not the same as the one you show, but illustrates what you want to do.)
2) Creating instances and pointers to instances of a struct, then initializing.
3) Contains link to tutorial on self referencing structs. (as you are doing in your posted code)
typedef struct {//struct definition created in global space, typedef'ed
char line[80]; //to read in the line
int slot;
char type[20]; //long enough for any types listed
int position;
}SLOT;
int modifyStruct(SLOT *slot);//prototype of demonstration function
int main(void)
{
SLOT s;//create instance of SLOT local to main
int ret = modifyStruct(&s);pass address of SLOT instance to change member values
printf("Line: %s\n", s.line);//show changed values
printf("Slot: %d\n", s.slot);
printf("type: %s\n", s.type);
printf("position: %s\n", s.position);
return 0;
}
int modifyStruct(SLOT *slot)
{
strcpy(slot->line, "lineA");
slot->slot = 2;
strcpy(slot->type, "large");
slot->position = 20;
return 0;
}
EDIT - To address question in comment asking how to set a struct pointer to point to a struct.
First, it appears from viewing the code you have posted, that you are using self referencing structs. (i.e. a struct that contains a member that is a pointer instance to itself) Here is a link to a good tutorial dealing with Linked Lists in C, which use self referencing structs.
Regarding you comment: _I guess I should have made it more clear. P1_Semaphore is different to semaphore. I need P1_semaphore to point to the semaphore_.:
If P1_Semaphore is different than semaphore, then one should not be set to point to the address of the other. And your compiler will not let you do that anyway.
As I stated in the comments, a struct pointer should only point to a place in memory that contains an instance of that struct. For example consider the two structs A & B:
typedef struct {
int iNum;
float fNum;
char cStr[80];
}A;
A a, *pA; //create an instance, and pointer to an instance of A
typedef struct {
int iNum1;
int iNum2;
int iNum3;
}B;
B b, *pB; //create an instance, and pointer to an instance of B
A & B are obviously different, and will occupy a different size and shape in memory, so if the pointer to B, *pB was set to point to anything but B, it would be incorrect. It needs to point to B
Correct:
pA = &a //set pointer to A equal to the address of A
pB = &b //set pointer to B equal to the address of B
Incorrect:
pA = &b //set pointer to A equal to the address of B
pB = &a //set pointer to B equal to the address of A
(typical compiler error - Operands of = have types pointer to B and pointer to A)
In C/C++, all parameters are passed by value, not by reference. To get the struct pointer in parameter, you need to use pointer to pointer as the parameter. Like this:
int P1_SemCreate(char *name, unsigned int value, P1_Semaphore **sem){
...
*sem = temp;
...
}

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

Resources