Segmentation Fault when using scanf with 3 input variables - c

Not sure why I'm getting a segmentation fault here:
//I define the variables used for input
int *numberOfDonuts;
numberOfDonuts = (int *)malloc(sizeof(int));
char *charInput;
charInput = (char *)malloc(sizeof(char));
int *numberOfMilkshakes;
numberOfMilkshakes = (int *)malloc(sizeof(int));
//Then attempt to read input
scanf("%c %d %d", &*charInput, &*numberOfDonuts, &*numberOfMilkshakes);
Then I get a segmentation fault on this line. Can't work out what I'm doing wrong?

You're overcomplicating things with the way you're allocating your variables.
This should do what you want:
int numberOfDonuts;
char charInput;
int numberOfMilkshakes;
scanf("%c %d %d", &charInput, &numberOfDonuts, &numberOfMilkshakes);
With basic types like int and char you don't have to explicitly allocate memory for them. The compiler handles that for you.
Even allocating them the way you did, though, what you end up with is a pointer to the value rather than the value itself. Given that scanf wants a bunch of pointers there's no need to dereference the pointer and then get it's address again, which is what you're trying to do. The following will work as well:
int *numberOfDonuts;
numberOfDonuts = malloc(sizeof(int));
char *charInput;
charInput = malloc(sizeof(char));
int *numberOfMilkshakes;
numberOfMilkshakes = malloc(sizeof(int));
scanf("%c %d %d", charInput, numberOfDonuts, numberOfMilkshakes);

As far as I can tell, this code is valid.
It compiles on my system and works as expected.
Is this your whole program?
You should also note that all those pointers are not required.
You could just write it like this:
int numberOfDonuts;
char charInput;
int numberOfMilkshakes;
//Then attempt to read input
scanf("%c %d %d", &charInput, &numberOfDonuts, &numberOfMilkshakes);
printf("char=%c donuts=%d milkshakes=%d\n",
charInput, numberOfDonuts, numberOfMilkshakes);

Segmentation faults occur when the program tries to access invalid memory locations.
Since you use malloc in your program to allocate memory, it is always best to check whether a valid memory location is returned before attempting to store a value in that location. Include this check every time malloc is used in your program to resolve the error.
For eg:
int *numberOfDonuts = (int *)malloc(sizeof(int));
if(numberOfDonuts == NULL)
{
printf("Memory allocation Failure\n");
return;
}

Related

Segmentation error while returning a pointer from an array using malloc() in C

maybe it's a dumb question but I'm new in C. I'm trying to return a pointer from a function using malloc. I made an array with strtok. Here it's the code of the function from which I'm trying to return the pointer:
int *data(){
int longi=0, *array=(int *) malloc(4 * sizeof(int));
char buffer[1024];
char *aux;
printf("Enter if approved(A) or failed (F) separated by a comma \",\": \n");
fgets(buffer,1023,stdin);
aux=strtok(buffer, ",");
while(aux)
{
array[longi]=aux;
longi++;
aux=strtok(NULL, ",");
}
printf("%s", array[0]);
return array;
}
And here is my main function:
int main(){
int *arr=data();
printf("%s",arr[0]); /*segmentation error */
return 0;
}
The segmentation fault occurs because you are trying to print part of your array as a string (%s). When using %d or %c (with char casting) it does not give that error.
However, it still doesn't make sense, since you are trying to put a pointer to the beginning of a string inside an array of integers. I'd suggest allocating an array of characters instead of integers, and making sure you've got a single character inside aux, then adding it to the array. You also need to make sure you don't accept more than 4 different characters, otherwise you might still have a buffer overflow.
printf when flag is %s is trying to read string from allocated memory, you giving an integer so this why it gives a segfault
replace array[longi]=aux; with array[longi]=atoi(aux); atoi will convert from string to integer, and for both printfs replace %s with %d

Segmentation fault when finding string length

Function to calculate string length; I think the logic here is correct:
int strlength(char *s)
{
int count=0;
while(*s!='\0')
{
count++;
s++;
}
return count;
}
int main(void) {
char *s;
int length;
printf("enter your string ");
scanf("%s",s);
length = strlength(s);
printf("string length:%d",length);
return 0;
}
Am I taking the string correctly here and assigning it? Can anyone please explain why I get segmentation fault here?
Your s has to point to something. Here is an example of allocating 128 bytes:
s = malloc(128);
Be sure to release the memory once you're done with it:
free(s);
Note that you must limit how much can be read from the user.
scanf("%127s", s);
I've left an extra byte for the NUL terminator.
this second line of the main() function is declaring a pointer. However, that pointer is never initialized to point to some memory block that the program owns.
Suggest using one of the heap allocation functions (malloc, calloc, realloc) to initialize that pointer.
Using that uninitialized pointer is undefined behavior and (as you saw) leads to a seg fault event.
when calling any of the scanf() family of functions,
always check the returned value (not the parameter values) to assure the operation was successful.
when using the '%s' input/format specifier, always include a MAX
CHARACTERS modifier that is one less than the length of the input
buffer to avoid any buffer overflow. Such overflow is undefined
behavior and can lead to a seg fault event.

Segmentation Fault when using malloc

I think I've got everything fixed now. I made the mistake of incrementing the environ variable instead of treating it like an array and iterating across it. The following is what I have now and it should be good to go.
extern char **environ;
int main(int argc, char *argv[]) {
// determine number of environment variables
int n = 0;
char *c = NULL;
while ((c = environ[n++]) != NULL) {
printf("%s\n", c);
}
printf("%s\n%d\n\n", c, n);
// allocate array to store character pointers to environment array
char **new_c;
printf("This prints\n");
if ((new_c = malloc(n * sizeof(*c))) == NULL) {
printf("Error\n");
exit(EXIT_FAILURE);
}
printf("This prints now too\n");
free(c);
// sort array of character pointers
// parse each environment variable and output
exit(0);
}
To start, I've read through a couple dozen malloc & segmentation fault questions on here and none seem to be the same as mine. That being said, if this is a duplicate question would you mine pointing me to the solution?
Hi all, I'm having a problem using malloc. I compiled and ran my program once and malloc worked. I then began filling in more code to solve the problem and since that first run I have received a Segmentation Fault. Below is my code in it's last working state (still giving a seg fault error though):
extern char **environ;
int main(int argc, char *argv[]) {
// determine number of environment variables
int n = 0;
char *c = *environ;
while ((c = *environ++) != NULL) {
n++;
printf("%s\n", c);
}
printf("%s\n%d\n\n", c, n);
// allocate array to store character pointers to environment array
printf("This prints\n");
if ((c = malloc((size_t) n)) == NULL) {
perror("Unable to allocate memory\n");
}
printf("This does not print\n");
free(c);
// sort array of character pointers
// parse each environment variable and output
exit(0);
}
The program is supposed to allocate memory for a char array that will then be used to sort, parse, and print the name-value or value-name pairs depending on what the FORMAT value is set to. The first loop works and iterates through the environ variable and prints out each name-value pair. The two printf statements I included state what I see in the terminal. Does anyone have any ideas what I'm doing wrong?
Also, I have tried using the following malloc lines:
char *new_c = malloc((size_t) n);
char *new_c = malloc(n);
char *new_c = malloc(1);
char *new_c = malloc(sizeof(n));
int *ptr = malloc((size_t) n);
There are probably a few others I tried but I'm still baffled. There are so few lines of code that I'm not sure how I could be messing anything up this early on. Also, for giggles here's what I get when I use free in the terminal (showing I have memory available):
total used free shared buff/cache available
Mem: 3036836 1404340 902852 104712 729644 1491248
Swap: 0 0 0
I've also tried calling malloc outside of the if statement as such:
c = malloc((size_t) n);
if (c == NULL) {
perror("Unable to allocate memory\n");
}
Here you are modifying the global environ:
while ((c = *environ++) != NULL) {
After the while loop, environ points to uninitialized memory.
malloc() looks for some environment variables which can modify its behaviour and is now dereferencing a pointer to uninitialized memory.
Use this:
int i = 0;
while ((c = environ[i++]) != NULL) {
This should fix the segmentation fault.
Two things with this:
if ((c = malloc((size_t) n)) == NULL) {
perror("Unable to allocate memory\n");
}
You are allocating n bytes, here. It sounds like you want to allocate space for n pointers to char, so you should replace with:
malloc(n * sizeof(char *))
If this is indeed what you're trying to do, then c should be char **, not char *, and better still would be:
c = malloc(n * sizeof *c)
Incidentally, you appear to be using c for two completely different things. It's generally better not to do this with variables - since it makes your program harder to understand - and instead to use one variable to loop through to print your environment variables, and a different one to store your dynamically allocated array.
Also, you call perror() if malloc() fails, but then you just continue right on with your program as if there was no error. You should actually respond to a failure of this nature, if nothing else by calling exit(EXIT_FAILURE) after reporting it.

C sprintf function crashing my program

I'm watching a course online learning C and I stumbled upon something that is crashing my program.
In the video they show the following code snippet :
#include <stdio.h>
int main()
{
char* ch;
int num = 12345;
sprintf(ch, "%d", num);
printf("%s\n", ch);
return(0);
}
I've decided to make my own little program and test it.
Here's the code I've written :
#include <stdio.h>
#define A 65
int main()
{
int n = A;
printf("n is equal to %d\n", n);
n = atoi("10");
printf("n is equal to %d\n", n);
char* ch;
sprintf(ch, "%d", n);
printf("ch is equal to %s\n", ch);
return 0;
}
When I run my program, the output is as follow :
n is equal to 65
n is equal to 10
After this part my program crashes.
I assume the sprintf function is causing this but I'm not sure why, I'm new to the language so I wouldn't know, I think I've done everything correctly judging by the code snippets that was shown in the video.
Could someone please explain me what I did wrong ?
Thanks in advance.
In the video they show the following code snippet: [...]
If this is a snippet that they say should work, stop watching that video: the snippet has undefined behavior, there is no chance that it would work properly unless by an unlucky coincidence.
I've decided to make my own little program and test it.
Your program has the same exact problem: the buffer to which sprintf is writing has not been initialized. Change the declaration of ch to allocate some space to it, like this:
char ch[20];
This will prevent your code from writing to memory pointed to by an uninitialized pointer, fixing the undefined behavior.
Could you explain to me how char* could be used?
If you would like to use char*, assign it a result of malloc of a proper size, and free the result at the end:
char *ch = malloc(20);
... // Put the rest of the code here
// Add this line before the end:
free(ch);
You need to alocate memory for ch or else use an array instead of a pointer.
char* ch = malloc(sizeyouwant * sizeof(char));
Where sizeyouwant is the number of characters you will store.
The problem is here:
char* ch;
this is just a char pointer, it needs to point to allocated memory to hold the string:
char ch[32];

segmentation fault during execution

#include<stdio.h>
int main()
{
char *arg[10],*c;
int count=0;
FILE *fp,*fq;
printf("Name of the file:");
scanf("%s",arg[1]);
fp=fopen(arg[1],"w");
printf("\t\t%s",arg[1]);
printf("Input the text into the file\n");
printf("Press Ctrl+d to the stop\n");
while((*c=getchar())!=EOF)
{
fwrite(c,sizeof(char),1,fp);
count++;
}
return 0;
}
Change this line
char *arg[10],*c;
to
char arg[1000],c;
This line
scanf("%s",arg[1]);
to
scanf("%s",arg);
And this line
while((*c=getchar())!=EOF)
to
while((c=getchar())!=EOF)
Explanation:
char *c; is not a character. It's a pointer to a character. It starts out just pointing to a random bit of memory, which will often be filled with random data - whatever was most recently written there.
char c; is a character.
The same thing applies to char *arg[10]. It's an array of ten pointers. They point into random memory, filled with random data.
Note: my change is not best practice. If someone were to type in a filename 1000 characters or more long, you'd write over the end of the arg buffer. Depending on what you're doing, this can be a security bug.
In
char *arg[10];
you define an array of 10 pointers to char but you do not initialize its elements. arg[0], arg[1], ..., arg[9] will all have undefined values.
Then, you try to enter a string into one of those undefined values. Lucky you, you got a segmentation fault. Had you been unlucky, your program could format your hard disk instead.
char *arg[10] ;
arg is array of char pointers. You need to assign them memory locations using malloc before taking input -
scanf("%s",arg[1]); // arg[1] is not assigned to point to any memory location
// and is what causing the segmentation fault.
So do -
arg[1] = malloc( stringLengthExpectedToEnter + 1 ) ; // +1 for termination character
Should do like that with the rest of array elements too (or) simply change char*arg[10] to char arg[10] and make sure to enter only enter 9 characters.
I think you are confusing between a pointer and a normal variable.
int *ptr;
ptr is variable that can hold the address of an integer variable. Memory is allocated to for ptr variable to hold an integer address. That's it. ptr is in an uninitalized state and is pointing no where (or) might be pointing to garbage. Dereferencing an uninitialized pointer's behavior is undefined and you are lucky enough if it gives a segmentation-fault.
Now, you need to assign it a valid memory location using malloc.
ptr = malloc( sizeof(int) ) ; // Allocates number of bytes required to hold an
// integer and returns it's address.
So, ptr is now pointing to memory location acquired from free store that can hold an integer. Such acquired locations from free stored must be freed using free, else you have classical problem of memory leak. It is good practice to initialize pointer to NULL while declaration.
int *ptr = NULL ;
Hope it helps !
scanf("%d", ptr) ; // Notice that & is not required before ptr. Because ptr
// content is address itself.
A normal variable story is entirely different. When declared -
int var ;
Memory is allocated to var to hold an integer. So, you can directly assign it an integer.
#include<stdio.h>
int main()
{
char arg[10],c;
int count=0;
FILE *fp;
printf("Name of the file:");
scanf("%s",arg);
fp=fopen(arg,"w");
printf("\t\t%s",arg);
printf("Input the text into the file\n");
printf("Press Ctrl+d to the stop\n");
while((c=getchar())!=EOF)
{
fwrite(&c,sizeof(char),1,fp);
count++;
}
if(fp != NULL){
fclose(fp);
fp = NULL;
}
return 0;
}

Resources