Why are my C structure declarations not being recognized? - c

I am developing a TIN model application and have a structure 'Vertex' that I have defined in the common area at the top of my C program.
struct Vertex
{
int GblSeqNum;
int PlySeqNum;
struct Polyline *Line;
double CtrZ;
double x;
double y;
double z;
struct Edge *OwnerEdge;
struct Vertex *NextVtx;
struct Vertex *PrevVtx;
};
Next, right below the Vertex structure, I declare a global pointer to a Vertex structure:
struct Vertex *VtxsInLines;
Then, still in the common area, I use calloc to assign space for my vertices:
VtxsInLines = (struct Vertex *)(calloc(15000, sizeof(struct Vertex)));
I compile the code using GNU C compiler using MinGW on Windows 10:
C:\000WORKIndexedTasks 000-999\500 Papers\523 PositionalAccuracyContourLines>gcc -c 523*.c
The following warnings and errors are generated:
523Paper_ReadContourVertices.c:98:1: warning: data definition has no type or storage class
VtxsInLines = (struct Vertex *)(calloc(15000, sizeof(struct Vertex)));
^~~~~~~~~~~
523Paper_ReadContourVertices.c:98:1: warning: type defaults to 'int' in declaration of 'VtxsInLines' [-Wimplicit-int]
523Paper_ReadContourVertices.c:98:1: error: conflicting types for 'VtxsInLines'
523Paper_ReadContourVertices.c:47:16: note: previous declaration of 'VtxsInLines' was here
struct Vertex *VtxsInLines;
^~~~~~~~~~~
523Paper_ReadContourVertices.c:98:15: warning: initialization of 'int' from 'struct Vertex *' makes integer from pointer without a cast [-Wint-conversion]
VtxsInLines = (struct Vertex *)(calloc(15000, sizeof(struct Vertex)));
It appears my declarations are in error somehow and this leads the compiler to assume an int type. This generates lots of errors later such as:
523Paper_ReadContourVertices.c: In function 'main':
523Paper_ReadContourVertices.c:432:20: error: invalid type argument of '->' (have 'int')
(VtxsInLines+idx)->GblSeqNum = -1;
Can you tell me with what what I provided what I am doing wrong?

The problem is that you are allocating the Vertex structure in the global space. It is not permissible to run executable instructions in the global scope, only allowed in functions such as main. The fix would be to move the VtxsInLines = (struct Vertex *)(calloc(15000, sizeof(struct Vertex))); statement into the main function. You would still be able to access the memory assigned to the VtxsInLines variable in other functions without having to pass it along because VtxsInLines is global.

Related

pointer confusion - error: passing argument 1 of ‘value’ from incompatible pointer type; note: expected ‘...’ but argument is of type ‘...'

EDIT: This was so obvious, I have no idea how I didn't notice. Thanks for your help, guys!
I am making a symbol table using binary tree in C, and I got stuck while defining the basic functions. I have never been able to fully grasp pointer operations, and these errors are making my head hurt and I have no idea how to fix them, although I'm sure that many of you will find my problem trivial.
I have a structure defined like this:
typedef struct SymTable {
symbol_t *rootNode;
} symTable_t;
An initialisation function like this:
void initTable(symTable_t *table) {
table->rootNode = NULL;
}
And in my main.c I call the function:
symTable_t *newTable = malloc(sizeof(symTable_t));
// check if malloc was successful
initTable(&newTable);
It throws these two errors when I try to translate:
main.c:12:12: error: passing argument 1 of ‘initTable’
from incompatible pointer type [-Werror=incompatible-pointer-types]
initTable(&newTable);
^
In file included from main.c:1:0:
sym_tab.c:18:7: note: expected ‘symTable_t * {aka struct SymTable *}’ but argument is of type ‘symTable_t ** {aka struct SymTable **}’
void initTable(symTable_t *table) {
When I define initTable() like _initTable(symTable_t table)_, it only throws more errors.
Thank you in advance.
You're passing a pointer to a pointer to a symTable_t instead of just a pointer to a symTable_t.
Remove the & in this line:
initTable(&newTable);
and the error will go away.

Incompatible pointer types 'struct tGlobal::instrStack *' and 'instrStack *'

I have a small warning problem.
I have a global struct including all neccesary thing (flags, list of allocated memory etc.).
Its a global structure. So Im using it in all program.
Now I wanted to add there a pointer on instruction stack so I can just get to the datas like global.iStack
The structure of global is
struct tGlobal{
.. some other thing in structure
struct instrStack *iStack;
struct mainTree *mTree;
};
extern struct tGlobal global;
And I have to initialize the stack. So I have a function with this prototype
instrStack* instrStackInit (instrStack* stc );
So in main I'm doing this
struct instrStack dummyInstrStack;
global.iStack = instrStackInit(&dummyInstrStack);
But the Clion is displaying warning like Incompatible pointer types 'struct tGlobal::instrStack *' and 'instrStack *'
But I'm adding pointer on that stack so there should be problem. Or I'm I wrong?
This thing happening mor etimes. Again in global struct when i want for sxample init the Binary tree and pointer on it insert into structure so I can easily acces the data wherever I want.
Can anyone help me and tell me what I'm doing wrong?
E: Declaration of instrStack
typedef struct {
Instr **dataInstr;
int count;
int alloc;
}instrStack;

How to properly allocate memory for structs, arrays of structs inside a struct, and passing that array as a parameter

I've been quite aways away from C and as I am diving back into it I have found myself hitting a roadblock. I have the following structure:
typedef struct{
char id;
struct S *children[SIZE];
}S;
In my code I initially declare an array of structs...
struct S arr[SIZE];
But when I get to this point of trying to allocate my first child for my first member of arr...
arr[0].children[0] = (S*)malloc(sizeof(S));
I get this warning: warning: incompatible implicit declaration of built-in function ‘malloc’ warning: assignment from incompatible pointer type [enabled by default]
On top of this I'm getting an error that doesn't sound very logical to me. I have the following function:
int foo(S *children[SIZE]);
but when I call this line....
foo(arr[0].children);
I get this note: note: expected ‘struct S **’ but argument is of type ‘struct S **’
which to me just sounds silly, it is expecting the argument it is getting and is upset about it.
Any help in explaining what I should be doing to properly allocate this memory and achieve the same idea would be very much appreciated.
There is no struct S, only S which is a typedef of anonymous structure.
Define struct S too:
typedef struct S {
char id;
struct S *children[SIZE];
}S;
Or:
typedef struct S S;
struct S {
char id;
S *children[SIZE];
};
And do avoid casting return of malloc in C:
arr[0].children[0] = malloc(sizeof(S));
For your first problem, you need to do:
#include <stdlib.h>
at the top of your program, in order to call malloc successfully.
The second problem (as also pointed out by others) is that struct S in your class definition refers to a different struct than S. In C, struct tags are in a different "namespace" than type names.

passing array of structure pointer to a function

I am writing a program in which I have to pass an array of structure pointers to a function in main body as follows
struct node *vertices[20];
create_vertices (&vertices,20);
implementation of function is some thing like this
void create_vertices (struct node *vertices[20],int index)
{
}
in this I have to pass an array of structure pointers with index 20,
the declaration I did outside mains is as follows I
void create_vertices(struct node **,int);
However each time compiling the code gives me problem in these three lines only as
bfs.c:26:6: error: conflicting types for ‘create_vertices’
bfs.c:8:6: note: previous declaration of ‘create_vertices’ was here
bfs.c: In function ‘create_vertices’:
bfs.c:36:15: error: incompatible types when assigning to type ‘struct node’ from type ‘struct node *’
I am unable to understand how should I be doing this.
What I want to be able to do is:
Declare an array of structure pointers in main (which I already did).
Pass the address of array to function (here is where I goofed up).
Declare the correct prototype of function outside mains.
The code has to be on C and I am testing it on Linux.
Can some one point me?
The type of &vertices in the call create_vertices(&vertices, 20) is not what you think.
It is a pointer to an array of pointers to structs:
struct node *(*)[20]
and not
struct node **
Drop the & in the call and you'd be back in business.
The compilation (using GCC 4.7.0 on Mac OS X 10.7.4):
$ gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -c x3.c
x3.c: In function ‘func1’:
x3.c:16:9: warning: passing argument 1 of ‘create_vertices’ from incompatible pointer type [enabled by default]
x3.c:7:10: note: expected ‘struct node **’ but argument is of type ‘struct node * (*)[20]’
$
The code:
struct node { void *data; void *next; };
void make_node(struct node *item);
void func1(void);
void create_vertices(struct node **array, int arrsize);
void create_vertices(struct node *vertices[20], int index)
{
for (int i = 0; i < index; i++)
make_node(vertices[i]);
}
void func1(void)
{
struct node *vertices[20];
create_vertices(&vertices, 20);
}
Drop the & and the code compiles cleanly.
As you wrote: struct node *vertices[20]; declares an array of pointers to node. Now if you want to create a function that changes its elements, you should declare a function that takes this kind of array as an argument:
void create_vertices(struct node *arr[20], int size)
or since the size can be ommited in this case, it's better to declare it as:
void create_vertices(struct node *arr[], int size)
Note, that this function can be called like this: create_vertices(vertices, 20); which makes first argument of this function (arr) to point to first element of this array. You are able to change this array within this function and changes will be visible outside.
Let's say you have function void foo(struct node *ptr) that changes node that ptr points to. When you declare struct node *ptr; and pass to this function: foo(ptr);, it can change this node object and changes are visible outside, but it can't change the passed pointer ptr itself. When you need to change pointer within the function so that changes are visible outside, that's the situation when you pass an address of pointer to function taking pointer to pointer.
In the prototype of create_vertices, the first argument is a pointer to a pointer to a structure. In the definition the first argument is array of 20 pointers to a structure.
Both the prototype and the definition has to be the same.

Defining the correct struct based on existing code

I've got some homework troubles with C struct… if anyone can be helpful. Because I don't get it.
The working code contains those bits (It's a game with a snake that has a head containing a direction):
game_t *game = …;
game->snake.head->direction = …;
snake_info(game->snake)
snake_destroy(&(game->snake));
The prototypes (I apparently cannot change):
void snake_info(snake_t const *snake);
void snake_destroy(snake_t *snake);
And the structure I'm trying to build.
typedef struct game {
snake_t snake; // to match call to snake_destroy and direction assignation
// or
snake_t *snake; // to match call to snake_info
} game_t;
But I cannot get both to work at the same time.
EDIT: the struct was called snake while it's actually game.
Do I miss something obvious or is there a problem with those prototypes (or calls)?
EDIT 2:
Compiler error with the first solution snake_t snake (in game):
snake.c: In function ‘game_print’:
snake.c:244:5: erreur: incompatible type for argument 1 of ‘snake_info’
gamecore.c:20:6: note: expected ‘const struct snake_t *’ but argument is of type ‘snake_t’
Compiler error with the second solution ̀ snake_t *snake`:
snake.c: In function ‘game_destroy’:
snake.c:205:5: attention : passing argument 1 of ‘snake_destroy’ from incompatible pointer type
gamecore.c:54:6: note: expected ‘struct snake_t *’ but argument is of type ‘struct snake_t **’
Your struct is incorrect. You have two members both with the same name 'snake'
Both must have unique names within the scope of the struct to permit legal code
The compiler error says it all, you have to define your struct using struct snake_t:
typedef struct game {
struct snake_t snake;
} game_t;
You have to use snake_t snake because of snake.head within the given code.
There is a bit of confusion with where pointers are used. With more practice using pointers will become more natural to you.
Also, use variable names that do not conflict with the names of structures.
Depending upon how much pointer usage you want in your code.
Minimal edits to existing code:
typedef struct game {
snake_t snake; // A snake_t instance is created with the game instance..
} game_t;
--
game_t *game = …;
game->snake.head->direction = …;
// snake_info requires a snake_t reference so pass the address of game->snake
//snake_info(game->snake);
snake_info(&(game->snake));
snake_destroy(&(game->snake));
Minimal pointers:
typedef struct game {
snake_t snake; // A snake_t instance is created with the game instance..
} game_t;
--
// Use a game_t variable instead of a pointer
//game_t *game = …;
game_t aGame = …; // renamed variable to avoid conflicts
// change the snake.head to snake->head since the game object uses a snake_t pointer
// game->snake.head->direction = …;
aGame.snake.head->direction = …;
// Pass the address of aGame.snake
snake_info(&(aGame.snake));
// this line is okay since you pass the address of game->snake.
snake_destroy(&(aGame.snake));
Making more use of pointers:
typedef struct game {
snake_t *snake; // A pointer to a snake_t instance.
} game_t;
--
// Create a game_t instance
game_t aGame = …;
// Create a snake_t instance
snake_t aSnake = ... ;
// Create a game_t pointer and assign it the address of aGame
game_t *aGamePtr = &aGame;
// Using aGamePtr, assign the snake variable in aGame the address of aSnake
aGamePtr->snake = &aSnake;
// Since the game_t object is a snake_t pointer,
// change the snake.head to snake->head
// game->snake.head->direction = …;
aGamePtr->snake->head->direction = …;
// this line is okay since aGamePtr->snake is a pointer.
snake_info(aGamePtr->snake);
// Since game object uses a snake_t pointer, pass aGamePtr->snake directly
// snake_destroy(&(game->snake));
snake_destroy(aGamePtr->snake);

Resources