Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I want to write a simple c code to create a garden structure,input details like num_animals, type of garden and size of garden.
However, my code is giving me some garbage output.
#include <stdio.h>
#include <string.h>
struct Garden
{
int num_animals;
int size;
char type[10];
};
void Input(struct Garden gardname)
{
printf("\nEnter number of animals\n");
scanf("%d",&gardname.num_animals);
printf("\nEnter size\n");
scanf("%d",&gardname.size);
printf("\nEnter type\n");
scanf("%s",gardname.type);
}
void Output(struct Garden gardname)
{
printf("Num of animals:%d\n",gardname.num_animals);
printf("size:%d\n",gardname.size);
printf("type:%s\n",gardname.type);
}
int main()
{
struct Garden Lumbini;
Input(Lumbini);
Output(Lumbini);
return 0;
}
The functions you have defined, by default use call by value method of passing arguments, which means that although you have Lumbini structure to which you intend to read and write elements, your functions will instead make a copy of Lumbini(in this case gardname), and write to, or print out that copy, not Lumbini. It may lead to duplicate values. I have written the same program using call by reference (note how a pointer to structure is the expected parameter in function, and the reference of lumbini is passed on call). This insures that there are no duplicates, and only the relevant structure (in this case, lumbini) is being manipulated.
#include <stdio.h>
#include <string.h>
struct Garden
{
int num_animals;
int size;
char an_type[10];
};
void Input(struct Garden *gardname)
{
printf("\nEnter number of animals\n");
scanf("%d", &gardname->num_animals);
printf("\nEnter size\n");
scanf("%d", &gardname->size);
printf("\nEnter type\n");
scanf("%s", gardname->an_type);
}
void Output(struct Garden *gardname)
{
printf("Num of animals:%d\n",gardname->num_animals);
printf("size:%d\n",gardname->size);
printf("type:%s\n",gardname->an_type);
}
int main()
{
struct Garden Lumbini;
Input(&Lumbini);
Output(&Lumbini);
return 0;
}
You are getting garbage values because gardname in Output function is a local variable to an uninitialized copy of lumbini structure. When you print out the values of gardname, they will be garbage values as they are not initialized. As the function finishes execution, gardname is destroyed.
Also, instead of writing
scanf("%d",&gardname.num_animals)
you must write
scanf("%d", &gardname->num_animals)
This will read into the address of pointer gardname plus the offset of member num_animals into the structure.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
First of all, this code is running without any issue on my linux desktop pc (x86_64) but on my Cyclone v (arm cpu/fpga), I have a segmentation fault because the value of the pointer is changing. The relevant line is the last one, during the for loop, the value of "layer->filename" is changing, it is correct during the first iteration (the address given by malloc) but it changes on the second one.
Basically, this bit of code is copying character from "buff" to "layer->filename", as you can see in the output file, the value of buff[i] is a valid character so it should not corrupt layer->filename.
If you have an idea of what could cause this issue, please let me know.
Thank you for your help.
typedef enum
{
CONV,
BN,
FC,
} layer_type;
typedef struct layer{
layer_type layer_type;
int shape[3];
char *filename;
} layer;
...
layer *layer=malloc(sizeof(layer));
char buff[30];
int i;
...
layer->filename = malloc(sizeof(char)*(n+1));
if(buff[0]=='b')
layer->layer_type=BN;
else if(buff[0]=='c')
layer->layer_type=CONV;
else
layer->layer_type=FC;
for(i=0; i<n ; i++)
*(layer->filename+i)=buff[i];
values of buff[i] and layer->name during the loop
Using this code
#include <stdio.h>
#include <stdlib.h>
typedef enum
{
CONV,
BN,
FC,
} layer_type;
typedef struct layer{
layer_type layer_type;
int shape[3];
char *filename;
} layer;
size_t test(size_t x) {
printf("%d\n", (int)x);
return x;
}
int main(void) {
layer *layer=malloc(test(sizeof(layer)));
return 0;
}
You can see that sizeof(layer) in the line
layer *layer=malloc(sizeof(layer));
is not the size of a structure but the size of a pointer.
This is because the name of variable is the same as the type name and the compiler treated layer in sizeof as the variable (pointer) name.
To avoid this and have it allocate the size of structure, you should change the name of type or variable to avoid confusion.
Dereferincing the pointer
layer *layer=malloc(sizeof(*layer));
also can solve this problem, but I think renaming is better.
This function is supposed to save data to a library.books_count instance of a dynamic array of pointers to structures. Yet it does not. A similar function addexistingBooks() does it flawlessly. What is the problem in realloc()?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
char book_name[32];
char book_genre[32];
char author[32];
int page_count;
float price;
}Sbook;
typedef struct
{
char library_name[32];
Sbook * bookp;
int books_count;
}Slib;
void menu(char String[50]);
void addexistingBooks(Slib library, int i);
void addBook(Slib library, int i);
int main()
{
Slib library;
int i=0;
char Choice[30];
printf("Enter amount of books inside the library: ");
scanf("%d", &(library.books_count));
library.bookp = (Sbook *)calloc(library.books_count,sizeof (Sbook));
fflush(stdin);
addexistingBooks(library, i);
menu(Choice);
if(strcmp(Choice,"add")==0)
{
addBook(library, i);
}
free(library.bookp);
return 0;
}
void menu(char String[30])
{
printf("Welcome to the library. If you read about heresy, prepare to be purged \n");
printf("Please choose a command, by writing the appropriate command: \n");
printf("1. Write 'add' to add a book. \n");
printf("2. Write 'remove' to remove a book. \n");
printf("3. Write 'redact' to redact a book. \n");
printf("4. Write 'Sort by criteria' to sort the books, where criteria can stand for: 1.bookname, 2.author, 3.genre, 4.price. \n");
printf("Enter your command: ");
gets(String);
}
void addexistingBooks(Slib library, int i)
{
for(i=0;i<library.books_count;i++)
{
printf("Enter the name of the book: \n");
fgets(library.bookp[i].book_name,32,stdin);
printf("Enter the genre of the book: \n");
fgets(library.bookp[i].book_genre,32,stdin);
printf("Enter the author of the book: \n");
fgets(library.bookp[i].author,32,stdin);
printf("Enter the page count of the book: \n");
scanf("%d", &(library.bookp[i].page_count));
printf("Enter the price of the book: \n");
scanf("%f", &(library.bookp[i].price));
fflush(stdin);
}
}
void addBook(Slib library, int i)
{
(library.books_count)++;
realloc(library.bookp,library.books_count);
fflush(stdin);
if(library.bookp==NULL)
{
exit(1);
}
printf("Enter the name of the book: \n");
fgets(library.bookp[i].book_name,32,stdin);
printf("Enter the genre of the book: \n");
fgets(library.bookp[i].book_genre,32,stdin);
printf("Enter the author of the book: \n");
fgets(library.bookp[i].author,32,stdin);
printf("Enter the page count of the book: \n");
scanf("%d", &(library.bookp[i].page_count));
printf("Enter the price of the book: \n");
scanf("%f", &(library.bookp[i].price));
fflush(stdin);
}
Your code contains several mistakes.
Lets start from the "non-blocking" mistakes. Those that, even if they can be really critical and have to be corrected, are not the real cause of the crash you experience.
The flush of standard input, fflush(stdin); is something that is not defined by the standard, so using it leads to undefined behavior: in some environments it could work, in some other environment it could not work, and there can be environments (the worst ones) in which it seems to work but it is actually harmful. It is recommended to avoid it.
Function gets() is dangerous because it doesn't provide any control on the size of the string inserted by the user, and its use should be avoided.
The issues in the void addBook() function
You try increasing the available space using realloc:
void *realloc(void *ptr, size_t size);
It needs the original pointer and the new size. But you pass library.books_count that is just the number of books. Meaning that, if the library used to contain 4 books, you try to allocate 5 bytes only.
You instead need to allocate library.books_count * sizeof(Sbook) bytes.
Furthermore it returns a new pointer. You need to assign it to the book pointer:
library.bookp = realloc(library.bookp, library.books_count * sizeof(Sbook));
In main() you initialize a i variable, but you never update it, since you store the numbers of books directly in library.books_count.
Then you pass it to addexistingBooks(), and it is redundant because you could use library.books_count itself for the loop, as you actually do. You can use it as the loop variable, but you don't need to have that parameter. Just
void addexistingBooks(Slib library, )
{
int i; /* If your C version is C99 or later, you can declare it in the loop itself */
for(i=0;i<library.books_count;i++)
{
/* Omissis */
}
}
Finally you pass it to addBook(), and not only it is redundant (as you can simply store the new book at index library.books_count-1, but it is actively harmful because you are always updating index 0 (because the value of parameter i is 0).
Although it is possible to pass structures to functions as values, it is not recommended. The first reason is that you will overload the stack of the process (the whole struct will be allocated in the stack area, that is quite big in PC applications but quite limited in embedded systems). The second reason will give you functional problems.
In fact, parameters passed by value are copies of the variables passed to the function. This means that any change made on them will not be reflected to original structures. In your case, the update of library.bookp pointer will not be available outside the function, causing (1) the original structure pointing to an invalid memory address location (becoming a dangling pointer), (2) the leak of the newly allocated memory, that nobody will be able to free().
Pass structures by address, instead, using pointers to structures. addBook() function, considering the i parameter removal, would become as follows
void addBook(Slib *library)
{
int i = library->books_count;
(library->books_count)++;
library->bookp = realloc(library->bookp, library->books_count * sizeof(Sbook));
/* and so on... the value of 'i' is now library->books_count-1 */
}
/* Call from main */
int main()
{
Slib library;
/* Omissis */
menu(Choice);
if(strcmp(Choice,"add")==0)
{
addBook(&library, i);
}
free(library.bookp);
return 0;
}
The definition of realloc function,
void *realloc(void *ptr, size_t size);
So, your realloc function:
realloc(library.bookp,library.books_count);
should change to:
library.bookp = realloc(library.bookp,sizeof(Sbook)*library.books_count);
OT, i see in your menu function, you use gets. It's dangerous, you should use fgets from stdin in stead. See in this link Why is the gets function so dangerous that it should not be used?
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
#include<stdio.h>
#define MAXSIZE 10
#define OK 1
#define NOK 0
int check_validity(int);
void input_array_elements(int,int *);
void Display_array_elements(int,int *);
int main()
{
int array[MAXSIZE];
int i,num,negative_sum=0,positive_sum=0;
float total=0.0,average;
printf("Enter the value of N\n");
scanf("%d",&num);
while(1)
{
int Return_val;
Return_val=check_validity(num);
if(Return_val == OK)
{
printf("sizeof array=%d\n",sizeof(array));
break;
}
else
{
printf("please enter a value <= 10\n");
scanf("%d",&num);
}
}
input_array_elements(num,&array[MAXSIZE]);
Display_array_elements(num,&array[MAXSIZE]);
}
int check_validity(int num)
{
if(num<MAXSIZE)
{
printf("OK\n");
return OK;
}
else
{
printf("NOK\n");
return NOK;
}
}
void input_array_elements(int num,int *array)
{
int i;
for(i=0;i<num;i++)
{
scanf("%d",&array[i]);
}
}
void Display_array_elements(int num,int *array)
{
int i;
for(i=0;i<num;i++)
{
printf("array[%d]=%d\n",i,array[i]);
}
}
What is "stack smashing"? How to solve this problem?
I'm compiling my program and I'm having error:
* stack smashing detected *: ./a.out terminated Segmentation fault (core dumped)
I don't know what I'm doing wrong.
The pointer to &array[MAXSIZE] is a pointer to one beyond the end of the array. That means your functions will start out of bounds of the array which leads to undefined behavior. The system detects is as a "stack smash" and crashes your program.
If you want to pass a pointer to the first element then use either &array[0], or plain array (as that will decay to &array[0]).
Segmentation fault (or stack smashing as you are getting) happens when you try to access a memory that is not accessible to your program or process.
In your function Display_array_elements I guess you are trying to print the array elements. The second argument should provide the address to the beginning of the array.
By passing &array[MAXSIZE] you are already pointing to the last element and then trying to access the other elements on this array, which is beyond valid array bounds. This is the reason for segmentation fault.
Change this call to one of the below
Display_array_elements(num,&array[0]);
OR
Display_array_elements(num,array);
Segmentation error comes when allocated memory space exceeds by a variable. Once variable declared, amount of memory is allocated in the stack.
Your array causing the problem. Hence array is defined to a particular size, next insertions going above the space and try to access the space of onother variable/ instruction.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
int doesn't seem to work with struct and I don't know why. I did the same thing as before and it worked but now it doesn't.
This is the main code.
int main()
{
struct elemente {
char *prod[20];
int cod[20];
int cant[20];
int pret[20];
};
struct elemente a[20];
int i,n=1,p[20];
char *val[20];
for(i=1;i<=n;i++){
puts("Numele produsului");
scanf("%s",&a[i].prod);
puts("Codul");
scanf("%i",&a[i].cod);
puts("Cantitatea");
scanf("%i",&a[i].cant);
puts("Pretul");
scanf("%i",&a[i].pret);
}
It works and I dont see it having problems.
This is where the problem is.
puts("Scrieti numele produsului");scanf("%s", &val);
for(i=1;i<=n;i++){
if(strcmp(val,a[i].prod)==0){
printf("Codul produsului: %i\n", a[i].cod);
printf("Cantitatea: %i\n", a[i].cant);
printf("Pretul: %i\n", a[i].pret);
//p[i]=a[i].cant*a[i].pret;
//printf("Valoarea totala a elementelor %i\n",p[i]);
}
}
The strcmp works fine. But it cannot find the integer numbers I have input with my scanf. It shows a strange code like "2303134". What did I do wrong?
Also as you can see I need to multiply 2 functions but CodeBlocks has problems with the * symbol. How can I fix this?
The problem is that your struct contains arrays of each element instead of a single one. This is also why the multiplication a[i].cant*a[i].pret won't compile, because you're attempting to multiply two int [20] instead of 2 int.
Since you create an array of struct elemente, you only need to input one element in each one:
struct elemente {
char prod[50];
int cod;
int cant;
int pret;
};
You would then change the scanf call to read in prod as follows to make sure you don't read more characters than the value can handle:
scanf("%49s",a[i].prod);
Also, be sure to check the return value of scanf to see whether a value was actually read in.
The strange code, in
printf("Codul produsului: %i\n", a[i].cod) case, is because you try to print the address of a[i].cod instead of the value of integer.
The easiest way to fix this is modify your struct to:
struct elemente {
char *prod[20];
int cod;
int cant;
int pret;
};
It seems there's no requirement to assign int arrays in your struct, int variables are sufficient.
After this modification,
p[i]=a[i].cant*a[i].pret;
printf("Valoarea totala a elementelor %i\n",p[i]);
should be ok to work.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Please help, I need to read an input txt file into an array and print it out put somehow I keep getting error message.
#include <stdio.h>
void reading_into_array(int A[]);
#define MAXVALS 100
int
main(int argc, char *argv[]){
int numbers[100], i;
reading_into_array(numbers[MAXVALS]);
for(i = 0; i < 100; i++){
printf("%d", numbers[i]);
}
return 0;
}
/*input information*/
void
reading_into_array(int A[]){
double inp;
int n = 0;
while(scanf("%lf",&inp) == 1){
A[n++] = inp;
}
}
numbers[MAXVALS] is out-of-range and its type doesn't match with the function argument. use numbers instead.
Avoid using values of uninitialized variables having automatic storage duration, which invokes undefined behavior. Initialize numbers like int numbers[100]={0},i;
When calling a function that takes an array as a parameter, you only need to supply the name of the array, e.g. numbers. "numbers[MAXVALS]" would supply the value of the MAXVALth element of this array. This is wrong for two reasons:
the function needs an array, not an element
The array has a size MAXVAL; its elements are counted from zero to MAXVAL-1, so the MAXVALth element does not even exist
If you want floating point numbers in your array, declare the array as double A[MAXVAL] everywhere.
Last note: the reading_into_array function should have a check that it will prevent it from putting more than MAXVAL numbers into the array, or you risk that it will corrupt memory and crash your program.