C dynamic memory allocation for table of structs - c

Hi here is my code. I want to dynamincly change no of elemnts in table with structs __state:
typedef struct __state{
long int timestamp;
int val;
int prev_value;
}*state_p, state_t;
int main(int argc, char **argv){
int zm;
int previous_state = 0;
int state = 0;
int i = 0;
int j;
state_p st;
//here i want to have 20 structs st.
st = (state_p) malloc(sizeof(state_t) * 20);
while(1){
previous_state = state;
scanf("%d", &state);
printf("%d, %d\n", state, previous_state);
if (previous_state != state){
printf("state changed %d %d\n", previous_state, state);
// here i got compile error:
main.c: In function ‘main’:
main.c:30: error: incompatible type for argument 1 of ‘save_state’
main.c:34: error: invalid type argument of ‘->’
main.c:34: error: invalid type argument of ‘->’
save_state(st[i],previous_state, state);
}
i++;
}
return 0;
}
I suppose i have to change that st[i] to smth like st+ptr ? where pointer is incermeting in each loop iteration ? Or am I wrong ? When i change code: initialization into state_p st[20] and in each loop iteration i put st[i] = (state_p)malloc(sizeof(state_t)) everything works fine, but i want to dynammicly change number of elemets in that table.
Thx in advance for any help

You don't show the prototype for save_state. I'm assuming the first parameter should be a pointer to a state. If that's the case, then you need:
save_state(st + i, previous_state, state);
or
save_state(&(st[i]), previous_state, state);

Related

Warnings when passing arguments to a function

So I have a code that works how it has to work, but I am getting the "warning: passing argument 2 of 'outsideBettingHistory' from incompatible pointer type", why is that?
My project is huge so I will only rewrite parts that play the role in the warning, so you can paste it yourself and get the same errors.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct Bet {
char* bets[3][2];
} Bet;
void outsideBettingHistory(int x, char betChosen[0][10], bool won, int result) {
//You can ignore what is inside this function
FILE *f;
f = fopen("bettingHistory.txt", "a");
if(!f) {
printf("\nThe bettingHistory.txt not found or unable to open");
exit(0);
}
if(won) {
fprintf(f, "%s %s", "Bet type: ", betChosen[0]);
fprintf(f, ". Won %d credits\n", result);
}
if(!won) {
fprintf(f, "%s %s", "Bet type: ", betChosen[0]);
fprintf(f, ". Lost %d credits\n", result);
}
fclose(f);
}
int betColours(int balance, Bet* betTypes) {
//A lot of stuff that have nothing to do with the warning
int typeOfBet = 0; //This is the example of 3 variables that this function would give to the outsideBettingHistory(); function
bool won = false;
int resultAmount = 8;
outsideBettingHistory(typeOfBet, betTypes->bets[0][typeOfBet], won, resultAmount);
return balance;
}
int main() {
int balance = 100;
Bet betTypes = { .bets={{"Red", "Black"}, {"Even", "Odd"}, {"1 to 18", "19 to 36"}}};
betColours(balance, &betTypes);
}
Also, for void outsideBettingHistory(int x, char betChosen[0][10], bool won, int result) I am getting "note: expected 'char (*)[10]' but argument is of type 'char *'" How do I get rid of these warnings?
In this call
outsideBettingHistory(typeOfBet, betTypes->bets[0][typeOfBet], won, resultAmount);
the second argument has the type char * because the data member bets is a two-dimensional array of pointers of the type char * and you selected the element of the array bets[0][typeOfBet] that is the same as bets[0][0] because typeOfBet was initialized by 0. That is you passed to the function a pointer to the first character of the string literal "Red".
But the second parameter of the function outsideBettingHistory
void outsideBettingHistory(int x, char betChosen[0][10], bool won, int result) {
has the type char ( * )[10].
And the types are not compatible. So the compiler issues an error.
You should decide for yourself what you are trying to pass to the function and what the function shall do.
If it is supposed that the function outsideBettingHistory must deal with a string literal (an element of the two-dimensional array) then declare the function like
void outsideBettingHistory(int x, const char *betChosen, bool won, int result) {

How can I pass an array of structures to another function

I am trying to pass an array of structs as pointer in another function. But the compiler just refuses.
I build up this code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Values{
char timestamp[21];
char temperature[2];
int tmp;
};
char *readString(char out[], FILE *fp){// Reading and storing the input values, out = the string that this func returns
int ch, i;
while(EOF!=(ch=fgetc(fp)))
if(ch == '"') break;
for(i=0;EOF!=(ch=fgetc(fp));++i){
if(ch == '"') break;
out[i] = ch;
}
out[i]='\0';
return out;
}
void printValues(struct Values * v, int i){ //just a printing method, for printing the values, i = the amount of values I have
int j;
for(j=0; j<i; j++){
printf("%s \t : \t %s \t :\t %d \n\n", v[j]->timestamp, v[j]->temperature, v[j]->tmp);
}
}
void makeTmpIntegers(struct Values values[], int i){ //making temperatures integers so I can use them in sorts, i = the amount of values I have
int j;
for(j=0; j<i;j++){
values[j].tmp = atoi(values[j].temperature);
}
}
int main(void){ //The beginning of the programm, what did you expect?
struct Values values[8223];
FILE *file = fopen("hum.txt", "r" );
int i=0; //the number of every stored value (for the timestamps)
int k=0; //the number of every stored value (for the temperatures)
if (file != NULL ){
char tempString [21];
int flag = 1;
while(*readString(tempString, file)){ //if the readStrinf outputs "/0" == "" (end of FILE)
if(flag == 1){strcpy(values[i].timestamp, tempString); flag++; i++;}
else if(flag == 2){strcpy(values[k].temperature, tempString); flag--; k++;}
}
fclose(file);
}
makeTmpIntegers(values, i);
printValues(&values, i);
return 0;
}
I know for a fact that I can pass the struct from a function to another (it works fine that way), but I want to pass pointers (memory reasons).
I have been trying to do it at the function called printValues()
In this case the compiler does not compile. This is the message I get:
In function 'printValues':
24 46 [Error] invalid type argument of '->' (have 'struct Values')
24 63 [Error] invalid type argument of '->' (have 'struct Values')
24 82 [Error] invalid type argument of '->' (have 'struct Values')
In function 'main':
53 17 [Warning] passing argument 1 of 'printValues' from incompatible pointer type
21 6 [Note] expected 'struct Values *' but argument is of type 'struct Values (*)[8223]'
Plus if I initialize the function like this: void printValues(struct Values * v[], int i)
It does compile but it does not prints the values at all
I know that the correct way to read an integer from a txt file, is not like this but I couldn't figure something else out
This is OK:
struct Values{
char timestamp[21];
char temperature[2];
int tmp; };
So are these two function signatures:
void printValues(struct Values * v, int i) { ... }
void makeTmpIntegers(struct Values values[], int i) { ... }
This is WRONG:
v[j]->timestamp, v[j]->temperature, ...
Substitute:
v[j].timestamp, v[j].temperature, ...
ALSO:
Change printValues(&values, i); to printValues(values, i);
I haven't checked carefully for any other errors, but this should get you moving in the right direction...
ADDENDUM:
In both of the examples above, printValues(struct Values * v, int i) and makeTmpIntegers(struct Values values[], int i), you're ALREADY "passing by pointer". You just need to fix your syntax, as in my examples.
As Oppen said below:
Also, note that passing an array argument in C is functionally
equivalent to passing a pointer, no copy is involved, so I'm not sure
what memory reasons stop you from just passing the array of structs
directly...

Passing struct into function

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 100000
typedef struct {
int day;
int month;
int year;
} DATE;
typedef struct {
char name[100];
int age;
float hrlyWage;
float hrsWorked;
float regPay;
float otPay;
float totalPay;
DATE payDate;
} PAYRECORD;
int newRecord(struct PAYRECORD record[], int index){
//set name to \0 so it can work as string
record[index].name = {'\0'};
index++;
return index;
}
int main(){
char menuChoice = 'X';
struct PAYRECORD record[SIZE];
int index = 0;
while (menuChoice != 'Q'){
system("pause");
system("cls");
menuChoice = runMenu();
switch (menuChoice){
case 'A':
index = newRecord(record, index);
}
}
}
main sets up an array of structs the gets passed into newRecord, and the goal is to make it so that I can input the data here and then return the new index to keep track of my array of structs. However something is going wrong where my program doesn't seem to be recognizing newRecord as a function, which ends up throwing the whole program off.
I get syntax errors for all the functions inside of newRecord, though I beleive it's because, as I mentioned, the program seems to be unable to recognize newRecord as a User defined Function.
Use of struct PAYRECORD is wrong since there is no such type. You only have a typedef named PAYRECORD.
If you want to be able to use struct PAYRECORD as well as just PAYRECORD, change the definition of the struct to:
typedef struct PAYRECORD {
char name[100];
int age;
float hrlyWage;
float hrsWorked;
float regPay;
float otPay;
float totalPay;
DATE payDate;
} PAYRECORD;
If that's not your goal, change the use of struct PAYRECORD by just PAYRECORD.
Also, the line:
record[index].name = {'\0'};
in newRecord is not correct. You cannot assign to an array like that. Change it to:
record[index].name[0] = '\0';
The struct PAYRECORD does not exist, the compiler has no idea how big that is.
Note that PAYRECORD is a typedef to an anonymous struct. So your function
should look like this:
int newRecord(PAYRECORD record[], int index){
//set name to \0 so it can work as string
record[index].name[0] = 0;
index++;
return index;
}
Also note that {'\0'}; works only when initializing a array when you declare
it:
char arr1[10] = { '\0' }; // OK
char arr2[10];
arr2 = { '\0' }; // NOT OK
// error: expected expression before ‘{’ token
// a = { '\0' };
// ^
And when writing functions that take arrays as an argument, you should also pass
the size of the array.
int newRecord(PAYRECORD record[], int index, size_t len){
if(record == NULL)
return -1; // error, NULL passed
if(index >= len)
return -1; // error, cannot access array
record[index].name[0] = 0;
index++;
return index;
}
And then you can call it from main like this:
PAYRECORD record[SIZE];
...
int index = 0;
if(newRecord(record, index, sizeof record / sizeof *record) != index)
{
// error handling
}
This makes the code more robust. You always have to check the array boundaries,
otherwise you might read/write out of bounds. And also check that NULL has not
been passed as well, if you dereference NULL, your program will crash with
segfault.
Also, the parameter to newRecord could be a PAYARRAY, not an array directly; based on declaring
typedef struct { } PAYRECORD, PAYARRAY[SIZE];
int newRecord(PAYARRAY record, int index) {...}
int main(){
...
PAYARRAY record;
...
case 'A':
index = newRecord(&record, index);
}
The compiler should be converting the PAYARRAY or PAYRECORD[] argument to a PAYRECORD * pointing to the first element, so use of the '&' is indicated for the function call.

C - Errors when trying to make a hashtable

I'm working on a hash table that stores strings in linked lists so I can avoid collisions. However, I'm getting two errors that I'm not sure how to fix. The first error I am getting is in the line that says NewT->Table[i] == NULL;. It's saying warning: statement with no effects [-Wunused-value].
The second error I'm getting is in the same function. The error is in the line return NewT and the error is warning: return from incompatible pointer type[enabled by default]. I've been staring at this for awhile and I can't see where there is an unused value and I have no idea what the return error means even after a bit of research. Can someone explain these to me and help me fix them?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define HASH_MULTIPLIER 65599
/*Structures*/
typedef struct List_T
{
char *str;
int count;
struct List_T *next;
} ListT;
typedef struct Hash_T
{
int htsize;
ListT **Table;
} HashT;
/*Prototypes*/
unsigned int hash(const char *str);
HashT **ht_create(void);
int htsize;
int main(int argc, char *argv[])
{
if (argc <= 1)
{
printf("Please declare a table size");
return 1;
}
htsize = atoi(argv[1]);
return 0;
}
unsigned int hash(const char *str)
{
int i;
unsigned int h = 0U;
for (i = 0; str[i] != '\0'; i++)
h = h * HASH_MULTIPLIER + (unsigned char) str[i];
return h % htsize;
}
HashT **ht_create(void)
{
HashT *NewT;
int i;
if (htsize < 1) //invalid size for
{
fprintf(stderr,"Invalid Size for table");
exit(0);
}
if ((NewT = malloc(sizeof(HashT))) == NULL)
{
fprintf(stderr,"Invalid size for table");
exit(0);
}
if ((NewT->Table = malloc(sizeof(ListT *) * htsize)) == NULL)
{
fprintf(stderr,"Invalid size for table");
exit(0);
}
for (i = 0; i<htsize; i++)
{
NewT->Table[i] == NULL;
}
NewT->htsize = htsize;
return NewT;
}
The first error I am getting is in the line that says NewT->Table[i]
== NULL;. It's saying warning: statement with no effects [-Wunused-value].
This error shows up because the code is making a comparison and not an assignment. The value returned by the comparison (is Table[i] null?) is itself not assigned to anything else, which means it's unused.
Keep a single = operator instead of the doubled == to make sure you're actually assigning instead of comparing.
The second error I'm getting is in the same function. The error is in
the line return NewT and the error is warning: return from
incompatible pointer type[enabled by default].
Your function claims to be returning a pointer to a pointer to HashT, or HashT **, but you end up returning a pointer to HashT, or HashT * instead, which is the type of your NewT variable.
Your function's signature should use a single * instead of two.

Writing a function to calculate number of elemets in a c ctruct

Hi i am writing a program to calculate the number of elements currently in a struct but i have the following error and am not sure how to fix them, thanks in advance
I have these errors:
structponters.c:4:30: error: array type has incomplete element type
void sizeStruct(struct point coordinates[]);
^
structponters.c:4:24: warning: ‘struct point’ declared inside parameter list
void sizeStruct(struct point coordinates[]);
^
structponters.c:4:24: warning: its scope is only this definition or
declaration, which is probably not what you want
structponters.c: In function ‘main’:
structponters.c:23:19: warning: assignment makes pointer from integer without a cast
sizeCoordinates = sizeof coordinates / sizeof coordinates[0];
^
structponters.c:28:14: error: type of formal parameter 1 is incomplete
sizeStruct(coordinates);
^
structponters.c: In function ‘sizeStruct’:
structponters.c:35:26: warning: comparison between pointer and integer
while(coordinates[i].x != NULL)
^
structponters.c:28: confused by earlier errors, bailing out
This is the code:
#include <stdio.h>
#include <stdlib.h>
void sizeStruct(struct point coordinates[]);
struct point{
int x;
int y;
};
main(){
struct point *pp = malloc(sizeof(struct point));
pp->x = 4;
pp->y = 7;
struct point coordinates[] = {{3,5}, {7,9}, {9,12}, {15, 19}};
int *sizeCoordinates = malloc(sizeof(int));
sizeCoordinates = sizeof coordinates / sizeof coordinates[0];
printf("%d, %d\n", pp->x, pp->y);
printf("size of coordinates is %d \n", sizeCoordinates);
sizeStruct(coordinates);
}
void sizeStruct(struct point coordinates[]){
int i =0;
while(coordinates[i].x != NULL)
i = i +1;
printf("number of elemets in coordinates is: %d\n", i);
}
#include <stdio.h>
#include <stdlib.h>
//Required before `sizeStruct` because sizeStruct use the `struct point`
struct point{
int x;
int y;
};
void sizeStruct(struct point coordinates[]);
int main(void){
struct point *pp = malloc(sizeof(struct point));
pp->x = 4;
pp->y = 7;
struct point coordinates[] = {{3,5}, {7,9}, {9,12}, {15, 19}, { 0, 0}};//{0,0} is sentinel
int sizeCoordinates;//no need malloc, just use int
sizeCoordinates = sizeof coordinates / sizeof coordinates[0];
printf("%d, %d\n", pp->x, pp->y);
printf("size of coordinates is %d \n", sizeCoordinates);
sizeStruct(coordinates);
free(pp);
return 0;
}
void sizeStruct(struct point coordinates[]){
int i =0;
while(coordinates[i].x != 0 && coordinates[i].y != 0)//!= NULL : Comparison of the int and pointer type incorrect
i = i + 1;
printf("number of elemets in coordinates is: %d\n", i);//The number of valid data
}

Resources