"struct" objects with "for-loop" in C Programming - c

This code is about 'struct' in C..
I created a struct spieler with the properties name and age..
By using the for-loop I let the user to create the struct objects.
they are named as sp[i] --> sp1, sp2 etc.
the problem is the objects are created. But I can use them only inside the for-loop.
If I want to get the value of "sp1.name" in main function, it doesn't work.
How can I solve it?
struct spieler{
char name[20];
int age;
};
void erzeuge();
int main() {
int anzahl = 2;
printf("Anzahl Spielern: ");
scanf("%d",&anzahl);
erzeuge(anzahl);
printf("Es sind %d Spielern",anzahl);
/*for(i;i<anzahl;i++){
printf("%d.%s",i, sp[i].name);
}*/
getchar();
}
void erzeuge(int anzahl){
int i=0;
for(i;i<anzahl;i++){
struct spieler sp[i];
printf("Struct fuer Spieler_%d wurde erzeugt\n", i);
getchar();
printf("Name: ");
scanf("%s",sp[i].name);
printf("%s\n",sp[i].name);
}

You should declare sp as a pointer at the global scope, and allocate memory for it inside the function erzeuge using malloc.
#include <stdlib.h>
#include <stdio.h>
struct spieler {
char name[20];
int age;
};
struct spieler *sp; // Add this
void erzeuge();
int main() {
int anzahl;
printf("Anzahl Spielern: ");
scanf("%d", &anzahl);
erzeuge(anzahl);
printf("Es sind %d Spielern\n", anzahl);
int i;
for(i = 0; i < anzahl; i++){
printf("%d.%s\n", i, sp[i].name);
}
if (sp) {
free(sp);
}
getchar();
return 0;
}
void erzeuge(int anzahl) {
// Add the following line to allocate memory
sp = (struct spieler*) malloc(anzahl * sizeof(struct spieler));
int i;
for (i = 0; i < anzahl; i++) {
// Remove the following line because it create an array of "i" elements
// struct spieler sp[i];
printf("Struct fuer Spieler_%d wurde erzeugt\n", i);
getchar();
printf("Name: ");
scanf("%s",sp[i].name);
printf("%s\n",sp[i].name);
}
}

You'd have to return an array of players from erzeuge, something like
struct spieler *erzeuge(int anzahl){
struct spieler *mannschaft = malloc(anzahl*sizeof(struct spieler));
int i;
for(i = 0; i < anzahl; ++i){
// prompt
scanf("%18s",&mannschaft[i].name);
...
}
return mannschaft;
}

Alternative solution without malloc:
void erzeuge(struct spieler* sp, int anzahl)
{
...
}
int main()
{
int anzahl = 2;
...
struct spieler sp[anzahl];
erzeuge(sp,anzahl);
...
}

Related

How to dynamically allocate vector and struct in a code?

I'm trying to allocate a struct and an array in the code below, but I have no idea how to proceed.
I'm trying to do this without adding other libraries.
It's in portuguese so I'm sorry if you don't understant the meaning.
struct RegistroAluno{
int Matricula;
char Nome[20];
int AnoNascimento;
};
int main()
{
int QuantidadeAlunos;
printf("Quantos alunos serão armazenados?\n");
scanf("%i", &QuantidadeAlunos);
struct RegistroAluno P1[QuantidadeAlunos];
struct *P1=(int *)malloc(QuantidadeAlunos*sizeof(struct));
for(int i=0; i<QuantidadeAlunos; i++){
printf("Qual a matrícula do aluno?\n");
scanf("%i", &P1[i].Matricula);
}/* I gotta do the same to all the other elements of the struct*/
return 0;
}
I'm trying to allocate a struct and an array
You allocate a variable length array (VLA) of struct RegistroAluno here:
struct RegistroAluno P1[QuantidadeAlunos];
Alternatively, you can allocate the array dynamically like this:
struct RegistroAluno *P1 = malloc(QuantidadeAlunos*sizeof(*P1));
Here the complete program with includes and error handling:
#include <stdlib.h>
#include <stdio.h>
struct RegistroAluno{
int Matricula;
char Nome[20];
int AnoNascimento;
};
int main(void) {
printf("Quantos alunos serão armazenados?\n");
int QuantidadeAlunos;
if(scanf("%i", &QuantidadeAlunos) != 1) {
printf("scanf failed\n");
return 1;
}
if(QuantidadeAlunos < 1) {
printf("QuantidadeAlunos must be > 0\n");
return 1;
}
struct RegistroAluno *P1 = malloc(QuantidadeAlunos*sizeof(*P1));
if(!P1) {
printf("malloc failed\n");
return 1;
}
for(int i=0; i<QuantidadeAlunos; i++){
printf("Qual a matrícula do aluno?\n");
if(scanf("%i", &P1[i].Matricula) != 1) {
printf("scanf failed\n");
return 1;
}
}
}
and example session:
Quantos alunos serão armazenados?
2
Qual a matrícula do aluno?
3
Qual a matrícula do aluno?
4

trying to add a variable of a certain type inside an array of that type

So i want to create an array of a structure that i made called jogo
Structure:
typedef struct jogo
{
int ident;/*idp of a product*/
char nome[1024]; /* string that describes a team eg. Barcelona */
char *equipas[2]; /*array of strings like {"Barcelona","Madrid"}*/
int score[2]; /*array of strings like {"Barcelona","Madrid"}*/
}* jogo;
I want to create an array without a specific size to store variables of type jogo.
When i type (add) a nome:equipa1:equipa2_score1:score2 like a elclassico:barcelona:madrid:1:0,i want to create a variable of type jogo and store it inside the array sistema_jog.
if i store something and the array is full i want reallocate the size of the array in order to store more variables of type jogo.
But for some reason im always getting segmentation fault core dumped when i try to do it and i dont know why.
Program:
#include<stdlib.h>
#include<stdio.h>
#include <string.h>
#define MAX_CHARS 1024 /* max characters of a word */
#define MAX_SIZE 5
int line = 1; /* counts the number of lines of the stdin */
static int size = MAX_SIZE;
int i = 0; /*ident of the variable jogo*/
int size_until = 0;
typedef struct jogo
{
int ident;/*idp of a product*/
char nome[MAX_CHARS]; /* string that describes a team eg. Barcelona */
char *equipas[2];
int score[2];
}* jogo;
jogo *sistema_jog;
void a(char nome[],char team1[],char team2[],int score1,int score2);
int team_not_in(char team1[],char team2[]);
int nome_in(char nome[]);
void cria_jogo(jogo s,char nome[],char equipa1[],char equipa2[],int score1,int score2);
int main() {
char c; char nome_jg[MAX_CHARS]; char eq1[MAX_CHARS]; char eq2[MAX_CHARS]; int pont1; int pont2;
sistema_jog = (jogo*) calloc(MAX_SIZE,sizeof(jogo));
while ((c = getchar())!= 'x') {
switch (c)
{
case 'a':
{
scanf("%1023[^:\n]:%1023[^:\n]:1023%[^:\n]:%d:%d",nome_jg,eq1,eq2,&pont1,&pont2);
i++;
printf("nome: %s",sistema_jog[0]->nome);
//a(nome_jg,eq1,eq2,pont1,pont2);
break;
}
}
}
return 0;
}
int nome_in(char nome[])
{
int i;
for(i=0; i < size; i++)
{
if (strcmp(sistema_jog[i]->nome,nome) == 0)
return 1;
}
return 0;
}
int team_not_in(char team1[],char team2[])
{
int i;
for (i=0;i<size;i++)
{
if((strcmp(sistema_jog[i]->equipas[0],team1) != 0) || (strcmp(sistema_jog[i]->equipas[1],team2) != 0))
return 1;
}
return 0;
}
void cria_jogo(jogo s,char nome[],char equipa1[],char equipa2[],int score1,int score2)
{
strcpy(s->nome,nome);
strcpy(s->equipas[0],equipa1);
strcpy(s->equipas[1],equipa2);
s->score[0] = score1;
s->score[1] = score2;
}
void a(char nome[],char team1[],char team2[],int score1,int score2)
{
int NL = line;
if (nome_in(nome) == 1)
printf("%d Jogo existente.",NL);
else if (team_not_in(team1,team2) == 0)
{
printf("%d Equipa existente.",NL);
}
else
{
jogo novo_jogo = (jogo) calloc(sizeof(jogo),sizeof(jogo));
cria_jogo(novo_jogo,nome,team1,team2,score1,score2);
if (size_until <= MAX_SIZE)
{
sistema_jog[size_until] = novo_jogo;
size_until++;
}
else
{
sistema_jog = (jogo*) realloc(system, sizeof(jogo)*size_until);
sistema_jog[size_until] = novo_jogo;
size_until++;
}
}
}
I am not surprised that you are confused.
As Christian Gibbons, Barmar and user12986714 said jogo must be your jogostruct and not a pointer to jogo. I supposed you changed, at some stage, } jogo; to }* jogo; because of compilation errors. But, it was not the original problem and after you are confused.
Let me explain shortly, try this basic code :
#include<stdlib.h>
#include<stdio.h>
#include <string.h>
#define MAX_CHARS 1024 /* max characters of a word */
#define MAX_SIZE 5
int line = 1; /* counts the number of lines of the stdin */
static int size = MAX_SIZE;
int i = 0; /*ident of the variable jogo*/
int size_until = 0;
typedef struct jogo
{
int ident;/*idp of a product*/
char nome[MAX_CHARS]; /* string that describes a team eg. Barcelona */
char *equipas[2];
int score[2];
}* jogo;
typedef struct jogo2
{
int ident;/*idp of a product*/
char nome[MAX_CHARS]; /* string that describes a team eg. Barcelona */
char *equipas[2];
int score[2];
} jogo2;
int main() {
printf("sizeof jogo %d\n",sizeof(jogo));
printf("sizeof jogo2 %d\n",sizeof(jogo2));
return 0;
}
As you could see jogo has a pointer size and jogo2 has the size of your struct.
More, there are various problems in your code. Everything is briefly commented directly in the code. Do not hesitate to ask questions.
#include<stdlib.h>
#include<stdio.h>
#include <string.h>
#define MAX_CHARS 1024
#define MAX_SIZE 5
int line = 1;
// static int size = MAX_SIZE; // Not useful. It is the same than MAX_SIZE
// int i = 0; this variable is not really used
int size_until = 0;
typedef struct jogo
{
// int ident; Never used
char nome[MAX_CHARS];
char equipas[2][1024]; // equipas is an array of two strings. If you use char *equipas[2], you will have to alloc memory for each string
int score[2];
} jogo; // * has been removed
jogo **sistema_jog; //sistema_jog is an array of pointer to jogo struct. You allocate it after.
// you could also have an array of jogo struct but it would need more modifications in your code.
// I suppose the confusion is here. To train, you could try to do : jogo * sistema_jog and to modify what it is needed in your code.
void a(char nome[],char team1[],char team2[],int score1,int score2);
int team_not_in(char team1[],char team2[]);
int nome_in(char nome[]);
void cria_jogo(jogo* s,char nome[],char equipa1[],char equipa2[],int score1,int score2); // *: s is a pointer to jogo struct. See comment on sistema_jog declaration
int main() {
char c; char nome_jg[MAX_CHARS]; char eq1[MAX_CHARS]; char eq2[MAX_CHARS]; int pont1; int pont2;
sistema_jog = (jogo**) calloc(MAX_SIZE,sizeof(jogo*)); // Each element of sistema_jog is a pointer to a jogo struct
while ((c = getchar())!= 'x') {
switch (c)
{
case 'a':
{
scanf("%1023[^:\n]:%1023[^:\n]:%1023[^:\n]:%d:%d",nome_jg,eq1,eq2,&pont1,&pont2); // be carefull, see % and 1023 in the third field of your code
// i++; not used elsewhere
a(nome_jg,eq1,eq2,pont1,pont2);
break;
}
}
}
// Only to check
for (int i=0; i<size_until;i++)
printf ("%s:%s:%s:%d:%d\n",
sistema_jog[i]->nome,
sistema_jog[i]->equipas[0],
sistema_jog[i]->equipas[1],
sistema_jog[i]->score[0],
sistema_jog[i]->score[1]);
return 0;
}
int nome_in(char nome[])
{
int i;
for(i=0; i < size_until; i++) // size_until : You have to check only elements that exist either you have less or more elements than size (static int = MAX_SIZE)
{
if (strcmp(sistema_jog[i]->nome,nome) == 0)
return 1;
}
return 0;
}
int team_not_in(char team1[],char team2[])
{
int i;
for (i=0;i<size_until;i++) // size_until : Idem as above
{
if((strcmp(sistema_jog[i]->equipas[0],team1) != 0) || (strcmp(sistema_jog[i]->equipas[1],team2) != 0))
return 1;
}
return 0;
}
void cria_jogo(jogo* s,char nome[],char equipa1[],char equipa2[],int score1,int score2) // * : s is a pointer to jogo struct
{
strcpy(s->nome,nome);
strcpy(s->equipas[0],equipa1);
strcpy(s->equipas[1],equipa2);
s->score[0] = score1;
s->score[1] = score2;
}
void a(char nome[],char team1[],char team2[],int score1,int score2)
{
int NL = line;
if (nome_in(nome) == 1)
printf("%d Jogo existente.",NL);
/* else if (team_not_in(team1,team2) == 0)
{
printf("%d Equipa existente.",NL);
} */ // I do not understand the objective of this test. So, I commented it. But it is not the question
else
{
jogo* novo_jogo = (jogo*) malloc(sizeof(jogo));
cria_jogo(novo_jogo,nome,team1,team2,score1,score2);
if (size_until < MAX_SIZE) // = has been removed. Index of array goes from 0 to size of array-1
{
sistema_jog[size_until] = novo_jogo;
size_until++;
}
else
{
sistema_jog = (jogo**) realloc(sistema_jog, sizeof(jogo**)*(size_until+1)); // *: see comment on sistema_jog declaration, +1: array index goes from 0 to size-1
// Remark : It is not efficient to realloc one by one. It would better to realloc MAX_SIZE by MAX_SIZE. You could try to do it
sistema_jog[size_until] = novo_jogo;
size_until++;
}
}
}

double free or corruption (!prev) in c , using thread, malloc

I'm tired about this problem. I use valgrind also. but I don't know why. Please find what is the problem in my code.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
static pthread_t *tid=NULL;
static int **data3=NULL;
typedef struct _Thdata
{
int *data;
int size;
int nthread;
} Thdata;
Thdata *tdata=NULL;
void *bubble(void *d){
Thdata *arr =(Thdata *)d;
int i,j,tmp;
int n=arr->size;
printf("thread #=%d n=%d\n",arr->nthread,n);
for(i=0;i<n;i++){
for(j=0;j<n-1;j++){
if((arr->data[j])>(arr->data[j+1]))
{
tmp = (arr->data[j]);
(arr->data[j])=(arr->data[j+1]);
(arr->data[j+1])=tmp;
}
}
}
for(j=0;j<n;j++)
printf("%d ",(arr->data[j]));
printf("\n");
pthread_exit((void *)1);
}
int main(int argc, char **argv){
FILE * fd;
int i,j;
int data[100];
int tcount = atoi(argv[1]);
int n = 100/tcount;
int err;
void *b;
//dynamic data
tid = (pthread_t *)malloc(tcount* sizeof(pthread_t));
data3 = (int **)malloc(tcount *sizeof(int*));
for( i=0; i<tcount; i++)
data3[i] = (int *)malloc((100/tcount) *sizeof(int));
tdata = (Thdata *)malloc(tcount*sizeof(Thdata));
for(i=0;i<tcount; i++) {
tdata[i].data =(int *)malloc(n*sizeof(int));
}
//dynamic data end
fd = fopen("data.txt", "r");
printf("tcount = %d n=%d\n",tcount,n);
// origin data
for(i =0; i<100;i++)
{
fscanf(fd, "%d",&data[i]);
printf("%d ", data[i]);
}
printf("\n");
for(j=0;j<tcount;j++){
for(i=0;i<n;i++){
data3[j][i]=data[n*j+i];
printf("%d ",data3[j][i]);
//tdata[j].data[i]=data[j][i];
}
printf("\n");
tdata[j].data=data3[j];
tdata[j].size=n;
tdata[j].nthread=0;
}
for(j=0;j<tcount;j++){
for(i=0;i<n;i++){
printf("%d ",tdata[j].data[i]);
}
printf("tdata[%d].size = %d",j,tdata[j].size);
printf("\n");
}
for(i =0; i<tcount;i++)
{
err=pthread_create(&tid[i],NULL,bubble,(void *)&tdata[i]);
if(err != 0)
printf("creat thread error");
tdata[i].nthread=i;
}
for(i=0;i<tcount;i++)
pthread_join(tid[i],&b);
for(i=tcount-1;i>=0;i--){
free(tdata[i].data);
}
free(tdata);
for(int i=tcount-1; i>=0; i--)
free(data3[i]);
free(data3);
free(tid);
fclose(fd);
return 0;
}
You assigned data3[j] to tdata[j].data as
tdata[j].data=data3[j];
so passing both of them to free() will cause double-free error as you said.
If you want to only copy pointers and copying values in data3[j] isn't needed, remove the part
for(i=0;i<tcount; i++) {
tdata[i].data =(int *)malloc(n*sizeof(int));
}
because the variable tdata[i].data will be overwritten later and memory leak will be caused. Also remove the part
for(i=tcount-1;i>=0;i--){
free(tdata[i].data);
}
because it will cause double-free error as descrived above.

Error in printing the stack

I am trying to implement a program using stacks.But the stack is not getting displayed
#include<stdio.h>
int size=0,count=1,test=0;
struct Car
{
int registrationNo;
char *name;
};
struct ParkingLot
{
struct Car C[10];
};
struct stack
{
struct ParkingLot P;
int top;
} st;
int stfull()
{
if(st.top >= size-1)
return 1;
else
return 0;
}
void push(struct Car item) {
st.top++;
st.P.C[st.top] = item;
}
int stempty() {
if (st.top == -1)
return 1;
else
return 0;
}
void display() {
int i;
if (stempty())
printf("\nStack Is Empty!");
else {
//printf("%d\n",st.top);
for (i = 0; i<=st.top; i++)
printf("\n%s", st.P.C[i].name);
}
}
void Enter_ParkingLot()
{
struct Car CC;
int checkFull=stfull();
if(checkFull==1)
printf("Parking Lot is FUll\n");
else
{
CC.registrationNo=count;count++;
char ch[100];
printf("Enter name of owner\n");
scanf("%s",ch);
CC.name=ch;
push(CC);
}
}
int main()
{
printf("Enter size of Parking Lot\n");
st.top=-1;
scanf("%d",&size);
Enter_ParkingLot();
Enter_ParkingLot();
display();
return 0;
}
This was my input on terminal-
Enter size of Parking Lot
2
Enter name of owner
ABCD
Enter name of owner
EFGH
This was my output-
`#
`#
There was a blank line before first # in the output.
If you assign the pointer field in struct Car to a local variable, it will not work, you need to redeclare your struct Car like this
struct Car
{
int registrationNo;
char name[100];
};
and then instead of
CC.name=ch;
do it this way
strcpy(CC.name, ch);
also, it's better to write
scanf("%99s",ch);
to prevent overflowing ch, and in your case it would be even better to do
scanf("%99s", CC.name);
I fixed your code
#include <stdio.h>
#include <string.h>
struct Car
{
int registrationNo;
char name[100];
};
struct ParkingLot
{
struct Car C[10];
};
struct stack
{
struct ParkingLot P;
int top;
} st;
int stfull(int size)
{
if(st.top >= size - 1)
return 1;
return 0;
}
void push(struct Car item)
{
st.P.C[++(st.top)] = item;
}
int stempty()
{
if (st.top == -1)
return 1;
return 0;
}
void display()
{
int i;
if (stempty() != 0)
printf("\nStack Is Empty!");
else {
for (i = 0 ; i <= st.top ; i++)
printf("\n%s", st.P.C[i].name);
}
}
int Enter_ParkingLot(int count, int size)
{
struct Car CC;
if (stfull(size) == 1)
printf("Parking Lot is FUll\n");
else
{
CC.registrationNo = count;
printf("Enter name of owner\n");
scanf("%99s", CC.name);
push(CC);
}
return count + 1;
}
int main()
{
int size = 0, count = 1;
printf("Enter size of Parking Lot\n");
st.top = -1;
scanf("%d", &size);
count = Enter_ParkingLot(count, size);
count = Enter_ParkingLot(count, size);
display();
return 0;
}
I removed global variables, they where not needed.
I fixed some if/else's which made no sense.
I also applied my previously suggested fixes related to your original problem.
The Problem:
You store the name of the car into an array that is allocated on the stack.
You then copy the pointer to that array to your car object.
The original array then goes out of scope.
You then try to print that array, which no longer exists, via the pointer.
Undefined behavior occurs.
The Solution:
You need to allocate memory for the name of the car with malloc() and use strcpy() to copy it to the car object.

Am I using structs in the wrong way?

I have come across this wierd and mysterous (at least to me) error that I am finding a very hard time finding. It gives me an error at the line where I call my function input(student_list1[MAX], &total_entries); where the compiler says:
incompatible type for agument 1 in 'input'
What am I doing wrong here? I sense it something very simple and stupid but I have gone through the code several times now without any avail.
#define MAX 10
#define NAME_LEN 15
struct person {
char name[NAME_LEN+1];
int age;
};
void input(struct person student_list1[MAX], int *total_entries);
int main(void)
{
struct person student_list1[MAX];
int total_entries=0, i;
input(student_list1[MAX], &total_entries);
for(i=0; i<total_entries; i++)
{
printf("Student 1:\tNamn: %s.\tAge: %s.\n", student_list1[i].name, student_list1[i].age);
}
return 0;
} //main end
void input(struct person student_list1[MAX], int *total_entries)
{
int done=0;
while(done!=1)
{
int i=0;
printf("Name of student: ");
fgets(student_list1[i].name, strlen(student_list1[i].name), stdin);
student_list1[i].name[strlen(student_list1[i].name)-1]=0;
if(student_list1[i].name==0) {
done=1;
}
else {
printf("Age of student: ");
scanf("%d", student_list1[i].age);
*total_entries++;
i++;
}
}
}
struct person student_list1[MAX] in the function argument is actually a pointer to struct person student_list1.
student_list1[MAX] you passed is a (out of bound) member of the array struct person student_list1[MAX]. Valid array index shoudl be between 0 to MAX - 1.
Change it to:
input(student_list1, &total_entries);
Note that here the array name student_list1 is automatically converted to a pointer to student_list1[0].
There are many things wrong with the code; this is my attempt at making it somewhat more robust:
#include <stdio.h>
#include <string.h>
#define MAX 10
#define NAME_LEN 15
// use a typedef to simplify code
typedef struct person {
char name[NAME_LEN];
int age;
} person_t;
// size qualifier on student_list is redundent and person_t* does the same
void input(person_t *student_list, int *total_entries);
int main(void)
{
person_t student_list[MAX];
int total_entries, i;
// pass array and not the non-existent 'student_list[MAX]' element
input(student_list, &total_entries);
for(i=0; i<total_entries; i++)
{
// age is an int, not a string so use %d
printf("Student 1:\tName: %s.\tAge: %d.\n", student_list[i].name, student_list[i].age);
}
return 0;
} //main end
void input(person_t *student_list, int *total_entries)
{
int done = 0, i = 0;
*total_entries = 0;
while (i < MAX) {
printf("Name of student: ");
// use NAME_LEN instead of strlen(list[i].name) because latter is
// probably not initialized at this stage
if (fgets(student_list[i].name, NAME_LEN, stdin) == NULL) {
return;
}
// detect zero-length string
if (student_list[i].name[0] == '\n') {
return;
}
printf("Age of student: ");
scanf("%d", &student_list[i].age);
// read the newline
fgetc(stdin);
*total_entries = ++i;
}
}
input(student_list1[MAX], &total_entries); shoud be input(student_list1, &total_entries);.
In C,
void input(struct person student_list1[MAX], int *total_entries);
equals
void input(struct person *student_list1, int *total_entries);

Resources