scanf of struct makes program crash - c

this is the code. the function "leggi" is supposed to read the value of c[i].a but when I type the first number in the console the program crashes.
It's probably a pointers issue but i can't figure it out
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct cane{
int a;
}cane;
void leggi(cane *c[20]){
int i;
for(i=0;i<5;i++)
scanf("%d", &c[i]->a );
}
int main(){
int i;
cane c[20];
leggi(&c);
for(i=0;i<5;i++)
printf("%d",c[i].a);
return 0;
}

You pass the wrong type to the function.
If you want to pass an array to a function the array name decays to a pointer to its first element, therefore the argument is only a pointer to the type:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct cane{
int a;
}cane;
void leggi(cane *c){
int i;
for(i=0;i<5;i++)
scanf("%d", &(c[i].a) );
}
int main(){
int i;
cane c[20];
leggi(c);
for(i=0;i<5;i++)
printf("%d",c[i].a);
return 0;
}

The type of &c is cane (*)[20] i.e. a pointer to an array. You've declared the argument of the function to be cane *[20] which is (as a function argument) a cane** which is a pointer to a pointer.
You may have intended to pass a pointer to an element of the array instead:
void leggi(cane *c)
// ...
scanf("%d", &c[i].a );
//
leggi(c);
Or possibly you really intended to pass a pointer to the array instead:
void leggi(cane (*c)[20])
scanf("%d", &(*c)[i].a )
//
leggi(&c);

Related

ADT (using a header file, source file and main file) in C

I am trying to create a simple ADT using a structure that takes 2 dates. Then returns an age. It must use a Header file, a source file for the Header file, and a main file.
This is what I have it runs and nothing happens. Can someone tell me what i am doing wrong?
age.h
#ifndef AGE_H_
#define AGE_H_
typedef struct getage * Age;
#define MAX 5
Age get_Age(int birthYear, int yearNow);
void age_Destroy(Age a);
#endif
age.c
#include <stdio.h>
#include "age.h"
struct getage {
int birthYear;
int yearNow;
};
Age a[1];
Age get_Age(int birthYear, int yearNow){
int giveAge = 0;
giveAge = a[0]->yearNow - a[0]->birthYear;
printf("%d",giveAge);
return 0;
}
void age_Destroy(Age a){
free(a);
}
main.c
#include <windows.h>
#include <stdio.h>
#include "age.h"
void age_print(Age a);
void age_print(Age a){
printf("%d\n", &a);
}
int main() {
Age a;
get_Age(1986, 2020);
age_print(a);
printf("%d\n", &a);
system("pause");
//age_Destroy(a);
}
What are wrong:
In the function get_Age:
Instead of allocating structures, a[0] (global variable, initialized to NULL) is dereferenced.
0 (converted to NULL) is returned instead of returning an age.
In the function age_Destroy:
free() is used without declaration nor including proper header.
In the function age_print:
Data having wrong type is passed to printf(): %d requests int but Age* is passed.
In the function main:
The return value of get_Age is dropped.
Data having wrong type is passed to printf(): %d requests int but Age* is passed.
Fixed code that won't cause Segmentation Fault nor undefined behavior:
age.h (not changed)
#ifndef AGE_H_
#define AGE_H_
typedef struct getage * Age;
#define MAX 5
Age get_Age(int birthYear, int yearNow);
void age_Destroy(Age a);
#endif
age.c
#include <stdio.h>
#include <stdlib.h> // for malloc() and free()
#include "age.h"
struct getage {
int birthYear;
int yearNow;
};
Age get_Age(int birthYear, int yearNow){
Age a = malloc(sizeof(*a)); // allocate a structure
if (a == NULL) { perror("malloc"); exit(1); }
a->yearNow = yearNow; // assign data
a->birthYear = birthYear;
int giveAge = 0;
giveAge = a->yearNow - a->birthYear;
printf("%d",giveAge);
return a; // return pointer to the allocated structure
}
void age_Destroy(Age a){
free(a);
}
main.c
#include <stdlib.h> // more portable header for system()
#include <stdio.h>
#include "age.h"
void age_print(Age a);
void age_print(Age a){
printf("%p\n", (void*)a); // use valid combination of format and data
}
int main() {
Age a;
a = get_Age(1986, 2020); // assign the return value
age_print(a);
printf("%p\n", (void*)a); // use valid combination of format and data
system("pause");
age_Destroy(a); // enable freeing
}
(Some behavior may look weird, but I believe this is valid because not desired behavior is described.)

C segmentation fault while using structures

I'm trying to write a data structure with two elements, and then defining a variable of that type struct. However, after initializing the variable in the main function, I'm getting segmentation fault and I don't know why.
#include <stdio.h>
#include <string.h>
struct AnimalSizes {
char stringName[50];
double sizeLength;
} animalSizes[2];
int main()
{
struct AnimalSizes *snakes;
strcpy(snakes[0].stringName,"Anaconda");
snakes[0].sizeLength=3.7;
strcpy(snakes[1].stringName,"Python");
snakes[1].sizeLength= 2.4;
printf("%c", *snakes[0].stringName);
printf("%lf", snakes[0].sizeLength);
printf("%c", *snakes[1].stringName);
printf("%lf", snakes[1].sizeLength);
return 0;
}
You try to strcpy to destination where is no allocated memory. That is undefined behavior.
You should first allocate enough memory to hold two AnimalSizes instances:
struct AnimalSizes *snakes;
snakes = malloc(2 * sizeof(struct AnimalSizes));
Also, here
printf("%c", snakes[0].stringName);
you are trying to output the first character of stringName. I assume, what you rather want to do is to output whole string with %s.
You've declared a pointer to a struct AnimalSizes, and you have declared an array struct AnimalSizes[2], but you have not made the pointer point to this array:
int main()
{
struct AnimalSizes *snakes = &animalSizes[0];
...
}
Alternatively, you may choose to not declare a global variable, rather choosing to allocate memory in main:
#include <stdlib.c>
#include <stdio.h>
#include <string.h>
struct AnimalSizes {
char stringName[50];
double sizeLength;
};
int main()
{
struct AnimalSizes *snakes = (struct AnimalSizes*) malloc(2*sizeof(struct AnimalSizes));
strcpy(snakes[0].stringName,"Anaconda");
snakes[0].sizeLength=3.7;
strcpy(snakes[1].stringName,"Python");
snakes[1].sizeLength= 2.4;
printf("%c", *snakes[0].stringName);
printf("%lf", snakes[0].sizeLength);
printf("%c", *snakes[1].stringName);
printf("%lf", snakes[1].sizeLength);
free(snakes);
return 0;
}
the following proposed code:
eliminates any need for malloc() and free()
performs the desired functionality
separates the definition of the struct from any instance of the struct.
inserts some spacing between the first letter of the snake name and the 'size' of the snake, for readability
applies certain other changes to the code for 'human' readability
and now the proposed code:
#include <stdio.h>
#include <string.h>
struct AnimalSizes
{
char stringName[50];
double sizeLength;
};
int main( void )
{
struct AnimalSizes snakes[2];
strcpy(snakes[0].stringName,"Anaconda");
snakes[0].sizeLength=3.7;
strcpy(snakes[1].stringName,"Python");
snakes[1].sizeLength= 2.4;
printf("%c ", snakes[0].stringName[0]);
printf("%lf\n", snakes[0].sizeLength);
printf("%c ", snakes[1].stringName[0]);
printf("%lf\n", snakes[1].sizeLength);
return 0;
}
a run of the proposed code outputs:
A 3.700000
P 2.400000

Value of variable changing when passing it to another function by reference

I have a project in which I have to make a basic database in C. My problem lies that keep passing a variable n from function to function and at one point the value changes.
I have made a test program which illustrates the same issue I'm having:
#include <stdio.h>
#include <stdlib.h>
void functionTWO(int *n)
{
printf("\n%d",*n);
}
functionONE(int *n)
{
int i=0;
i++;
i++;
*n = i;
printf("\n%d", *n);
functionTWO(&n);
}
int main()
{
int n=0;
printf("%d",n);
functionONE(&n);
return 0;
}
The n in the second function is displayed as a very very high number, e.g.:
0
2
2752268
Now, I know this probably is intended, but could you guys kindly explain why this happens this way?
In your functionONE(), n is already a pointer. You don't need to pass the address of the pointer if you intend to change that value-at-the-address.
As an advice, always check the data types and enable the compiler warnings to help you.
functionONE()
your are passing a address of address. So it's printing address of n.
Now you want a correct output then n as double pointer **n.
void functionTWO(int **n)
{
printf("\n%d",**n);
}
First of all, in C int & n is not the reference of n, it is it's address.Now, what you've done is created an int - sent it's address to functionONE - did something to the value in that address and then sent the the argument's address to functionTWO, instead of sending the argument itself, becuase it's already a pointer. Do this instead:
#include <stdio.h>
#include <stdlib.h>
void functionTWO(int *n)
{
printf("\n%d",*n);
}
functionONE(int *n)
{
int i=0;
i++;
i++;
*n = i;
printf("\n%d", *n);
functionTWO(n); // <-- send the pointer, not it's address
}
int main()
{
int n=0;
printf("%d",n);
functionONE(&n);
return 0;
}
In functionONE, n is int *, just a pointer, when you do functionTWO(&n);, you get the address of n, so it output a big value.
The value being printed in functionTWO function is the address of the pointer variable n declared in functionONE.In that case you can either modify functionTWO like this
void functionTWO(int **n)
{
printf("\n%d",**n);
}
or
Just pass the value of the pointer variable like this
functionTWO(n);

weird behaviour when working with double pointers

I need help to understand why in this little program i cannot manipulate correctly pointers:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void change(char *s[][15]){
int i=0;
while(i<5){
if(s[i][0]=='B') s[i][0]='v';
i++;
}
}
/*My code is supposed to allocate dynamically 5 arrays of 15 chars each
(like tab[5][15])and then put a message on them and try to modify the messages.
In this particular case i'm trying to change the first letter of each string to 'V'.
I'm doing this little experience because of another program
in which i have difficulties accessing double arrays*/
int main(){
int i;
char **s;
s =malloc(5*sizeof(char*));
for(i=0;i<5;i++){
s[i]=malloc(15*sizeof(char));
sprintf(s[i],"Bonjour%d",i);
}
change(s);
for(i=0;i<5;i++){
printf("%s\n",s[i]);
}
return 0;
}
I was expecting :
Vonjour0
Vonjour1
Vonjour2
Vonjour3
Vonjour4
but I get :
Bonjour0
Bonjour1
Bonjour2
Bonjour3
Bonjour4
I'm testing this little code for another program and I don't get why the arrays don't change.
In my other program I can't access the double pointer or print the content.
so my question is : why in this program I can't modify the content of the arrays ?
Your change method needs to use "char** s" instead of char *s[][15]. This is because your method is expecting a pointer to a multi-dimensional array. This is immutable as a result, since your original data type for the string is a pointer to an array of strings (IE: An array of chars).
Hopefully that was clear.
It should be
char **change(char **s){
int i=0;
while(i<5){
if(s[i][0]=='B') s[i][0]='v';
i++;
}
return s;
}
You only need to change the function argument to char *s[].
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void change(char *s[]){
int i=0;
while(i<5){
if(s[i][0]=='B') s[i][0]='v';
i++;
}
}
int main(){
int i;
char **s;
s =malloc(5*sizeof(char*));
for(i=0;i<5;i++){
s[i]=malloc(15*sizeof(char));
sprintf(s[i],"Bonjour%d",i);
}
change(s);
for(i=0;i<5;i++){
printf("%s\n",s[i]);
}
return 0;
}
Program output:
vonjour0
vonjour1
vonjour2
vonjour3
vonjour4

Sample program using Function Pointer and structures.

I created a structure and wanted to assign the values to a Function Pointer of another structure. The sample code I wrote is like below. Please see what else I've missed.
#include <stdio.h>
#include <string.h>
struct PClass{
void *Funt;
}gpclass;
struct StrFu stringfunc;
struct StrFu{
int a ;
char c;
};
Initialise(){
}
main()
{
stringfunc.a = 5;
stringfunc.c = 'd';
gpclass.Funt = malloc(sizeof(struct StrFu));
gpclass.Funt = &stringfunc;
memcpy(gpclass.Funt,&stringfunc,sizeof(struct StrFu));
printf("%u %u",gpclass.Funt->a,gpclass.Funt->c);
}
There are several problems:
A function pointer is not the same as void *, in fact you cannot rely on being able to convert between them.
You shouldn't cast the return value of malloc() in C.
You shouldn't call malloc(), then overwrite the returned pointer.
You don't need to use malloc() to store a single pointer, just use a pointer.
You shouldn't use memcpy() to copy structures, just use assignment.
There are two valid main() prototypes: int main(void) and int main(int argc, char *argv[]), and you're not using either.
there is lots of problem in your code , I try to correct it ,hope it will help
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct PClass{
void *Funt;
}gpclass;
struct StrFu{
int a ;
char c;
};
struct StrFu stringfunc;
int main()
{
stringfunc.a = 5;
stringfunc.c = 'd';
gpclass.Funt = malloc(sizeof(struct StrFu));
gpclass.Funt = &stringfunc;
memcpy(gpclass.Funt,&stringfunc,sizeof(struct StrFu));
printf("%d %c",((struct StrFu*)gpclass.Funt)->a,((struct StrFu*)gpclass.Funt)->c);
return 0;
}
it outputs
5 d

Resources