Reputation: 2721
I am writing a small c program to practicing malloc
and sscanf
library functions. But unfortunately I get a segmentation fault error. I have googled and struggled for hours but with no result. Anybody could lead me out of this?
#include <stdio.h>
#include <stdlib.h>
void print_array(int a[], int num_elements);
int main(void) {
int m;
printf("How many numbers do you count: \n");
scanf("%d", &m);
int *a = (int*)malloc(m * sizeof(int*));
char buf[100];
setbuf(stdin, NULL);
if (fgets(buf, sizeof buf, stdin) != NULL) {
char *p = buf;
int n, index;
while (sscanf(p, "%d %n", &a[index], &n) == 1 && index < m) {
// do something with array[i]
index++; // Increment after success @BLUEPIXY
p += n;
}
if (*p != '\0')
printf("you are giving non-numbers, will be ignored");
}
print_array(a, m);
free(a);
return 0;
}
void print_array(int a[], int num_elements) {
int i;
for (i = 0; i < num_elements; i++) {
printf("%d ", a[i]);
}
}
Upvotes: 3
Views: 226
Reputation: 144959
Your program has multiple errors:
you do not check the return value of scanf()
. Invalid input will cause m
to remain uninitialized, allocating m * sizeof(int)
may fail.
The size computed for malloc
is incorrect. Casting the return value of malloc()
is not necessary in C and considered bad style. Furthermore, you should check for allocation failure. Use this instead:
int *a = malloc(m * sizeof(int));
index
is uninitialized in sscanf(p, "%d %n", &a[index], &n)
definitely causing undefined behavior as you are telling sscanf()
to store the int
value into some random address in memory.
you test index < m
after storing to &a[index]
, causing a potential buffer overflow. Swap the test in front of the sscanf()
.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
void print_array(const int a[], int num_elements);
int main(void) {
int m;
printf("How many numbers do you count:\n");
if (scanf("%d", &m) != 1 || m <= 0) {
fprintf(stderr, "invalid input\n");
return 1;
}
int *a = malloc(m * sizeof(int));
if (a == NULL) {
fprintf(stderr, "memory allocation failed\n");
return 1;
}
char buf[100];
setbuf(stdin, NULL); // why do you want stdin to be unbuffered?
if (fgets(buf, sizeof buf, stdin) != NULL) {
char *p = buf;
int n, index = 0;
while (index < m && sscanf(p, "%d %n", &a[index], &n) == 1) {
// do something with array[i]
index++; // Increment after success @BLUEPIXY
p += n;
}
if (*p != '\0') {
printf("you are giving non-numbers or extra input, will be ignored\n");
}
}
print_array(a, m);
free(a);
return 0;
}
void print_array(const int a[], int num_elements) {
for (int i = 0; i < num_elements; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
Upvotes: 1
Reputation: 1319
Your malloc
is faulty. Replace int* a = (int*)malloc(m*sizeof(int*));
with int* a = (int *)malloc(m*sizeof(int));
.
You got lucky here, that sizeof
int
is smaller than int*
, otherwise you can get in whole bunch of problems.
I couldn't reproduce the error, better give input text next time, but to debug segfault i depend on gdb.
$ gcc -g prog.c -o prog
$ gdb prog
gdb> run [args]
This will break the program at line which is causing segfault. Use this tutorial for more knowledge. gdb tutorial
Upvotes: 3
Reputation: 25286
Most [potential] causes of errors seem to come from not initializing your automatic variables:
scanf("%d",&m);
If this fails, then m
has an undefined value as you didn't initialize it.
in sscanf
you use &a[index]
but index
has not been initialized so it can be written anywhere.
See also the comments, that identify more erors (e.g. checking the return value of sscanf
).
Upvotes: 0