Why the elements cannot be add in this stack? - c

I have this stack, and the elements of type NAMES(char), I'm trying to print all of the names of the array below (names) but I can't. Idk if the problem is in the STACK() function.
#define TAMMAX 30
typedef char NAMES[TAMMAX];
struct stack{
int nItems;
int capacity;
NAMES *names;
};
typedef struct stack Stack;
bool stack(Stack *st, NAMES *name){
if (st->capacity== st->nItems){
return false;
}
strcpy(st->names[st->nItems], *name);
st->nItems++;
return true;
}
int main(){
Stack *st;
NAMES *names[] = {
{"James"},
{"Kimberly"},
{"John"},
};
int nNames= sizeof(names) / sizeof(Stack);
for (int i = 0; i < nNames; i++){
stack(st, names[i]);
}
printStack(st);
return 0;
}
I have these warnings, I don't know how to fix them. The output of the code just print the first name of the array names: James.
stack.c:97:9: warning: braces around scalar initializer
97 | {"James"},
| ^
stack.c:97:9: note: (near initialization for 'postagens[0]')
stack.c:97:10: warning: initialization of 'char (*)[50]' from incompatible pointer type 'char *' [-Wincompatible-pointer-types]
97 | {"Kimberly"},
| ^~~~~~~~~~~
stack.c:97:10: note: (near initialization for 'postagens[0]')
stack.c:98:9: warning: braces around scalar initializer
98 | {"John"},
| ^

Related

How to output a big structure to another module in c?

Is there a best practice for ouput function parameters of big structures that should not be changed? return pointer to struct or return whole structure?
Example:
I have a big data structure in file A that i will call from file B: (typedef struct is in header)
.h
typedef struct
{
int x1;
int x2;
int x3;
int x4;
...
} myStruct;
.c
static myStruct data = {...};
errorType myfunction1(mystruct *outData)
{
*outData = data; //copy data to output
...
}
errorType myfunction2(mystruct **outData)
{
*outData = &data; //just return pointer to structure
...
}
myfunction1 copies the whole structure, so the stack size will rise if i will call this function a lot and the processing time is rising, but the advantage is that the original data could not be changed outside of this file like with myfunction2.
Is there a best practice what of the both to use?
I would use the const keyword for the parameter in myfunction2 so that
Case 1: At compilation any changes on a struct used in the caller would definitely make an error if the argument is also a const struct ;
Case 2: And at least a warning if the argument of the caller is not a const.
Case 1:
foo.h
#ifndef FOO_H
#define FOO_H
typedef struct fooStruct
{
int a;
int b;
int c;
}t_fooStruct;
void cpy_foo(const t_fooStruct ** structToCpy);
#endif
foo.c
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
t_fooStruct myData = {0,1,2};
void cpy_foo(const t_fooStruct ** structToCpy){
*structToCpy = &myData;
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
int main(){
const t_fooStruct * mainData;
cpy_foo(&mainData);
printf("After cpy print %d %d %d\n", mainData->a, mainData->b, mainData->c);
mainData->a = 10;
mainData->b = 20;
mainData->c = 30;
printf("After changes print %d %d %d\n\n", mainData->a, mainData->b, mainData->c);
return 0;
}
At compilation this gives:
main.c: In function 'main':
main.c:12:15: error: assignment of member 'a' in read-only object
12 | mainData->a = 10;
| ^
main.c:13:15: error: assignment of member 'b' in read-only object
13 | mainData->b = 20;
| ^
main.c:14:15: error: assignment of member 'c' in read-only object
14 | mainData->c = 30;
|
Case 2:
And if the structure is not a const in the main :
main.c (version without the const)
int main(){
t_fooStruct * mainData;
cpy_foo(&mainData);
[...]
At compilation this outputs:
9 | cpy_foo(&mainData);
| ^~~~~~~~~
| |
| t_fooStruct ** {aka struct fooStruct **}
In file included from main.c:3:
foo.h:12:35: note: expected 'const t_fooStruct **' {aka 'const struct fooStruct **'} but argument is of type 't_fooStruct **' {aka 'struct fooStruct **'}
12 | void cpy_foo(const t_fooStruct ** structToCpy);

passing argument 2 of ‘send_to_host’ from incompatible pointer type [-Wincompatible-pointer-types]

Getting these warnings when I used the below code snippet. Can any one help me to resolve?
new_str.c: In function ‘main’:
new_str.c:39:25: warning: passing argument 2 of ‘send_to_host’ from incompatible pointer type [-Wincompatible-pointer-types]
39 | send_to_host(MACRO,ram->s1);
| ~~~^~~~
| |
| stats_t * {aka struct stats_s *}
new_str.c:28:34: note: expected ‘int *’ but argument is of type ‘stats_t *’ {aka ‘struct stats_s *’}
28 | void send_to_host(int macro,int *data)
| ~~~~~^~~~
new_str.c:42:25: warning: passing argument 2 of ‘send_to_host’ from incompatible pointer type [-Wincompatible-pointer-types]
42 | send_to_host(MACRO,ram->a1);
| ~~~^~~~
| |
| abc_t * {aka struct abc_s *}
new_str.c:28:34: note: expected ‘int *’ but argument is of type ‘abc_t *’ {aka ‘struct abc_s *’}
28 | void send_to_host(int macro,int *data)***
#include <stdio.h>
#include <stdlib.h>
#define MACRO 12
typedef struct stats_s{
int tx;
int rx;
int err;
}stats_t;
typedef struct abc_s{
int a;
int b;
int c;
}abc_t;
typedef struct ram_s{
int dummy;
int dam;
stats_t *s1;
abc_t *a1;
}ram_t;
ram_t ram1;
void send_to_host(int macro,int *data) // 28
{
printf("function called\n");
}
void main(){
ram_t *ram;
ram = &ram1;
send_to_host(MACRO,ram->s1); // 39
send_to_host(MACRO,ram->a1); // 42
}
You need to send pointer to int (reference to int type struct member) not dereference pointer to struct (this pointer is not related to the type of the parameter).
send_to_host(MACRO,&ram -> s1 -> tx); // 39
send_to_host(MACRO,&ram -> a1 -> a); // 42
Below code is not needed at all.
ram_t *ram;
ram = &ram1;
simply:
send_to_host(MACRO,&ram1.s1 -> tx); // 39
send_to_host(MACRO,&ram1.a1 -> a); // 42
The main function signature has to be:
int main(void){
/* ... */

Passing and Returning structs C

So I have had this problem where I keep getting error codes only in my main that (1) The struct has already been defined when I keep my struct in a header file and (2) I am using incompatible pointer types.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "functDefs.h"
#include "writeToFile.c"
#include "readFile.c"
#include "inputContactInfo.c"
#include "contactInfoStruct.h"
int main(void) {
int i = 0;
char *ynAns;
struct contactId *contactInfo;
contactInfo = malloc(sizeof(struct contactId));
do {
if(ynAns != NULL) {
free(ynAns);
}
ynAns = malloc(sizeof(char) * 5);
printf("\nDo you wish to enter a new contact (Yes or No)?: ");
fgets(ynAns, 5, stdin);
ynAns[(strlen(ynAns) - 1)] = '\0';
if (strcmp(ynAns, "Yes") == 0) {
printf("\n");
contactInfo = realloc(contactInfo, sizeof(struct contactId) * (i + 1));
contactInfo[i] = inputContactInfo();
i++;
}
} while(strcmp(ynAns, "No") != 0);
writeToFile(contactInfo, i);
readFile(i);
free(contactInfo);
return 0;
}
Then here are my function definitions:
void writeToFile(struct contactId *contInfo, int numContacts);
struct contactId *inputContactInfo();
void readFile(int numContacts);
And this is the struct header file:
struct contactId {
char firstName[20];
char lastName[20];
char companyName[50];
char phoneNumber[15];
char email[50];
};
I get errors like:
IOlist.c: In function ‘main’:
IOlist.c:28:40: error: incompatible types when assigning to type ‘struct contactId’ from type ‘struct contactId *’
contactInfo[i] = inputContactInfo();
^
IOlist.c:34:21: warning: passing argument 1 of ‘writeToFile’ from incompatible pointer type
writeToFile(contactInfo, i);
^
In file included from IOlist.c:5:0:
writeToFile.c:7:6: note: expected ‘struct contactId *’ but argument is of type ‘struct contactId *’
void writeToFile(struct contactId *contInfo, int numContacts) {
^
And these errors as well:
In file included from IOlist.c:5:0:
writeToFile.c:7:6: error: conflicting types for ‘writeToFile’
void writeToFile(struct contactId *contInfo, int numContacts) {
^
In file included from IOlist.c:4:0:
functDefs.h:1:6: note: previous declaration of ‘writeToFile’ was here
void writeToFile(struct contactId *contInfo, int numContacts);
^
In file included from readFile.c:4:0,
from IOlist.c:6:
contactStruct.h:1:8: error: redefinition of ‘struct contact’
struct contact {
^
In file included from writeToFile.c:4:0,
from IOlist.c:5:
contactStruct.h:1:8: note: originally defined here
struct contact {
^
Your function inputContactInfo() returns a pointer to struct. But the place where it tries to returnn pointer is a struct. You need declare struct contactId **contactInfo, allocate memory for each element, and then you can correctly assign your pointer to contactInfo[i].

pointer inside struct to dynamic 2-D array

Hope you can help me since I'm a little desperate right now. Im working with threads and I want them all to modify the same 2D array. So I made a struct with a pointer to the 2D array, but it isn't working. This is my code
typedef struct {
char XY;
int b;
int d;
int f;
int h;
} celdaMatriz;
typedef struct {
int totalX;
int totalY;
celdaMatriz **matriz;
char direction;
int i;
int j;
int cont;
} parameter;
As you can see parameter has the variable " celdaMatriz matriz**" (I'm sorry about the spanish in my code). Now comes a function to initialize a "celdaMatriz" 2D array
void createMatriz(int totalX, int totalY, celdaMatriz **matriz[totalX][totalY])
{
int i,j;
for(i=0;i<totalX; i++){
for(j=0; j<totalX;j++){
matriz[i][j]->XY=' ';
matriz[i][j]->b=0;
matriz[i][j]->d=0;
matriz[i][j]->f=0;
matriz[i][j]->h=0;
}
}
matriz[0][3]->XY='/';
matriz[2][0]->XY='*';
matriz[2][1]->XY='*';
matriz[0][2]->XY='*';
matriz[2][2]->XY='*';
matriz[1][3]->XY='*';
matriz[3][3]->XY='*';
}
the function createMatriz will change, but that's the idea. So now my main function
int main( int argc,char *argv[])
{
int i,j;
celdaMatriz **matriz = malloc( sizeof (*matriz) * 4);
for (i=0; i < 4; ++i)
matriz[i] = malloc(sizeof (**matriz) * 4);
crateMatriz(4,4,matriz);
parameter *p1,p2;
parameter *p1 = malloc(sizeof(*p1));
p1->totalX=4;
p1->totalY=4;
p1->i=0;
p1->j=0;
p1->cont=0;
p1->direction= 'f';
p1->matriz= matriz;
return 0;
}
So anytime I want to create a new thread I create a new parameter variable and its "matriz" variable is a pointer to the 2D array I created in the main function. Well at least that's the idea, but I get these errors
**request for member 'XY' in something not a structure or union**
**request for member 'b' in something not a structure or union**
**request for member 'd' in something not a structure or union**
**request for member 'f' in something not a structure or union**
**request for member 'h' in something not a structure or union**
passing argument 3 of 'crearMatriz' from incompatible pointer type [enabled by default]
main.c: 59:6: note: expected 'struct celdaMatriz ** (*) [(unsigned int) (totaly)]' but argument is of type 'struct celdaMatriz **
The errors come from the createMatrix function and the last one from the main function. By the way I'm using linux and C.
Thanks. Hope you can help me.
EDITED
I just fixed an error, this
*passing argument 3 of 'crearMatriz' from incompatible pointer type [enabled by default]
main.c: 59:6: note: expected 'struct celdaMatriz * () [(unsigned int) (totaly)]' but argument is of type 'struct celdaMatriz *
is already fixed. So the problem now is that I'm accessing matriz[i][j]->XY=' '; incorrectly
Hope you can help me since I'm a little desperate right now. Im working with threads and I want them all to modify the same 2D array. So I made a struct with a pointer to the 2D array, but it isn't working. This is my code
typedef struct {
char XY;
int b;
int d;
int f;
int h;
} celdaMatriz;
typedef struct {
int totalX;
int totalY;
celdaMatriz **matriz;
char direction;
int i;
int j;
int cont;
} parameter;
As you can see parameter has the variable " celdaMatriz matriz**" (I'm sorry about the spanish in my code). Now comes a function to initialize a "celdaMatriz" 2D array
void createMatriz(int totalX, int totalY, celdaMatriz **matriz[totalX][totalY])
{
int i,j;
for(i=0;i<totalX; i++){
for(j=0; j<totalX;j++){
matriz[i][j]->XY=' ';
matriz[i][j]->b=0;
matriz[i][j]->d=0;
matriz[i][j]->f=0;
matriz[i][j]->h=0;
}
}
matriz[0][3]->XY='/';
matriz[2][0]->XY='*';
matriz[2][1]->XY='*';
matriz[0][2]->XY='*';
matriz[2][2]->XY='*';
matriz[1][3]->XY='*';
matriz[3][3]->XY='*';
}
the function createMatriz will change, but that's the idea. So now my main function
int main( int argc,char *argv[])
{
int i,j;
celdaMatriz **matriz = malloc( sizeof (*matriz) * 4);
for (i=0; i < 4; ++i)
matriz[i] = malloc(sizeof (**matriz) * 4);
crateMatriz(4,4,matriz);
parameter *p1,p2;
parameter *p1 = malloc(sizeof(*p1));
p1->totalX=4;
p1->totalY=4;
p1->i=0;
p1->j=0;
p1->cont=0;
p1->direction= 'f';
p1->matriz= matriz;
return 0;
}
So anytime I want to create a new thread I create a new parameter variable and its "matriz" variable is a pointer to the 2D array I created in the main function. Well at least that's the idea, but I get these errors
**request for member 'XY' in something not a structure or union**
**request for member 'b' in something not a structure or union**
**request for member 'd' in something not a structure or union**
**request for member 'f' in something not a structure or union**
**request for member 'h' in something not a structure or union**
passing argument 3 of 'crearMatriz' from incompatible pointer type [enabled by default]
main.c: 59:6: note: expected 'struct celdaMatriz ** (*) [(unsigned int) (totaly)]' but argument is of type 'struct celdaMatriz **
The errors come from the createMatrix function and the last one from the main function. By the way I'm using linux and C.
Thanks. Hope you can help me.
EDIT
I just fixed an error, this
*passing argument 3 of 'crearMatriz' from incompatible pointer type [enabled by default]
main.c: 59:6: note: expected 'struct celdaMatriz * () [(unsigned int) (totaly)]' but argument is of type 'struct celdaMatriz *
is already fixed. So the problem now is that I'm accessing matriz[i][j]->XY=' '; incorrectly
EDIT
Hi. I just want to let you know that I already found an answer to my problem. Instead of send a pointer to the matrix, I will use it as a global variable, that way all the threads will be able to modify it. So the solution is 1- Declare a global celdaMatriz **matriz
celdaMatriz **matriz;
Next I changed the memory allocation
matriz = (celdaMatriz **) malloc(4 * sizeof(celdaMatriz *));
for (i = 0; i < 4; ++i)
{
matriz[i] = (celdaMatriz *) malloc(4 * sizeof(celdaMatriz));
}
Finally the new void createMatriz function:
void crearMatriz(int totalX, int totalY)
{
int i=0,j=0;
for(i=0; i<totalX;i++){
for(j=0; j<totalY; j++){
celdaMatriz *nodo = malloc(sizeof(celdaMatriz));
nodo->b=0;
nodo->d=0;
nodo->f=0;
nodo->h=0;
nodo->casilla=0;
matriz[i+j*totalY]=(celdaMatriz *)nodo;
}
}
matriz[12]->casilla=1;
for(i=0; i<totalX; i++){
for(j=0; j<totalY; j++){
printf(" %d ", matriz[i+j*totalY]->casilla);
}
printf("\n");
}
}
And that's it. Thanks to all of you who helped me with this problem
I guess that the problem is that you tried to call creatMatriz like this,
createMatriz(p1->totalX, p1->totalY, p1->matriz);
and C (C99) does not like it. The problem is that p1->matriz is of type struct celdaMatriz **, but your prototype of createMatriz asked for a struct * (*) [totalY] because C ignores [totalX].
If you want to keep the definition of parameter unchanged, I would suggest you just use a double pointer.

Function pointer confusion

I'm trying to use function pointers and Abstract data types in c. This is my first time using it and I'm really confused. Anyways when I tried to compile this code I gave me an error. The first time I ran it worked. But when I change the arguments by switch a and b. It gave me the old answer and never updated.
typedef struct data_{
void *data;
struct data_ *next;
}data;
typedef struct buckets_{
void *key;
}buckets;
typedef struct hash_table_ {
/* structure definition goes here */
int (*hash_func)(char *);
int (*comp_func)(void*, void*);
buckets **buckets_array;
} hash_table, *Phash_table;
main(){
Phash_table table_p;
char word[20]= "Hellooooo";
int a;
a = 5;
int b;
b = 10;
/*Line 11*/
table_p = new_hash(15, *print_test(word), *comp_func(&a, &b));
}
int *print_test(char *word){
printf("%s", word);
}
int *comp_func(int *i,int *j){
if(*i < *j){
printf("yeeeeeeee");
}else{
printf("yeaaaaaaaaaaaaa");
}
}
Phash_table new_hash(int size, int (*hash_func)(char *), int (*cmp_func)(void *, void *)){
int i;
Phash_table table_p;
buckets *buckets_p;
hash_table hash_table;
table_p = (void *)malloc(sizeof(hash_table));
/*Setting function pointers*/
table_p -> hash_func = hash_func;
table_p -> comp_func = cmp_func;
/*Create buckets array and set to null*/
table_p -> buckets_array = (buckets **)malloc(sizeof(buckets_p)*(size+1));
for(i = 0; i < size; i++){
table_p -> buckets_array[i] = NULL;
}
return table_p;
}
This is the error message:
functions.c: In function 'main':
functions.c:11:26: error: invalid type argument of unary '*' (have 'int')
functions.c:11:45: error: invalid type argument of unary '*' (have 'int')
Helloyeaaaaaaaaaaaaa
New error:
functions.c:11:3: warning: passing argument 2 of 'new_hash' makes pointer from integer without a cast [enabled by default]
hash.h:29:13: note: expected 'int (*)(char *)' but argument is of type 'int'
functions.c:11:3: warning: passing argument 3 of 'new_hash' makes pointer from integer without a cast [enabled by default]
hash.h:29:13: note: expected 'int (*)(void *, void *)' but argument is of type 'int'
If you want to pass a function as a function-pointer, simply provide the name:
new_hash(15, print_test, comp_func);
or alternatively (and equivalently), use the & symbol to make it clear what's going on:
new_hash(15, &print_test, &comp_func);
You should declare function before using it. If you don't do this, the compiler assumes that it returns int, and gives you an error when you try to dereference it (since it's impossibole to dereference int).
EDIT:
you may also misunderstood the concept of function pointers. you should not pass the result of print_test(word) to new_hash - you should pass print_test itself. (also, change its return type)

Resources