Pointers Run time error - c

I have used the below code for a simple operation
(to reverse a string). But the program is not executing. It gets a run time error (SIGSEGV) . I used a GCC compiler. Please help me in debugging the program.
#include <stdio.h>
#include <stdlib.h>
int *create(int n) {
int *a;
a = (int *)malloc(n * sizeof(int));
return a;
}
void get(int *a, int n) {
int i;
for (i = 0; i < n; i++) {
scanf("%d", *(a + i));
}
}
void reverse(int *a, int n) {
int i;
for (i = n - 1; i >= 0; i--) {
printf("\n %d", *(a + i));
}
}
int main() {
int n, *a;
scanf("%d", &n);
a = create(n);
get(a, n);
reverse(a, n);
return 0;
}

scanf("%d",*(a+i)); invokes undefined behavior because you passed int where int* is expected.
You must pass pointer to tell scanf() where to store the data read, so stop dereferencing and try using scanf("%d",(a+i)); instead.
More notes are:
You should check if readings are successful.
They say you shouldn't cast the result of malloc() in C.

Related

I wrote a function to sort a string in alphabetical order but getting a segmentation fault

sort and swap functions take pointer as argument, when I try it with 2 or 3 strings it works fine but for more than three its giving a segmentation fault, this is my code please let me know what's going on here and why it's giving this error.
#include <stdio.h>
#include <string.h>
void get(int r, int c, char (*s)[c]);
void print(int r, int c, char (*s)[c]);
void sort(int r, int c, char (*s)[c]);
void swap(int c, char (*s)[c], char (*s1)[c]);
void main()
{
int r;
printf("\n\t enter no. : ");
scanf("%d", &r);
char s[r][31];
get(r,31,s);
sort(r,31,s);
printf("\n\tsorted list");
print(r,31,s);
}
void get(int r, int c, char (*s)[c])
{
int i, j;
for(i = 0; i < r; i++)
{
printf("\n\t");
scanf("%s", *(s+i));
}
}
void print(int r, int c, char (*s)[c])
{
int i, j;
for(i = 0; i < r; i++)
{
printf("\n\t%s", *(s+i));
}
}
void sort(int r, int c, char (*s)[c])
{
int i, j, k;
for(i = 0; i < r; i++)
{
for(j = 0, k = 1; j < r-1; j++, k++)
{
if(strcmp(*(s+j),*(s+k)) > 0)
{
swap(c, (s+j), (s+k));
}
}
}
}
void swap(int c, char (*s)[c], char (*s1)[c])
{
char (*t)[c];
strcpy(*t, *s);
strcpy(*s,*s1);
strcpy(*s1,*t);
}
t is a pointer and as such it needs to be initialized, that is the reason for the segmentation fault, you need to allocate and assign the needed memory though a way better solution would be to simply make it an array:
void swap(int c, char (*s)[c], char (*s1)[c])
{
char t[c];
strcpy(t, *s);
strcpy(*s,*s1);
strcpy(*s1,t);
}
Or
char (*t)[c] = malloc(sizeof *t); // you'll need stdlib.h
With this second option you must free the memory:
free(t);
I would strongly advise the first solution though.
I would also strongly advise the use of a width limiter for the scanf in your get function, otherwise you are at risk of buffer overflow and consequently of undefined behavior.
scanf("%30s", *(s+i));
// discard extra characters in case the input is larger than the destination buffer
while ((c = getchar()) != '\n' && c != EOF){}
Note that main return type should be int.
Live sample

Can somone please explain this to me

For n=3 and a={1,2,3},b={4,5,6} its supposed to calculate 1*4+2*5+3*6.
I don't understand why does it work because p is a pointer and p=produs(a,b,n) means that the address of p becomes the value returned by produs.
#include <stdio.h>
#include <conio.h>
void citire(int *x,int *n)
{
for(int i=1; i<=*n; i++)
scanf("%d",&x[i]);
}
int produs(int *a,int*b,int n)
{
int produs=0;
for(int i=1;i<=n;i++)
produs=a[i]*b[i]+produs;
return produs;
}
int main()
{
int n;
int*p;
scanf("%d",&n);
int *a=(int*)malloc(n*sizeof(int));
int *b=(int*)malloc(n*sizeof(int));
citire(a,&n);
citire(b,&n);
p=produs(a,b,n);
printf("%d",p);
return 0;
}
When you do:
size_t size = 10;
int* x = calloc(size, sizeof(int));
You get an array x with 10 items in it, indexed 0..9, not 1..10. Here calloc is used to make it abundantly clear what's being requested instead of doing multiplication that can be mysterious or obtuse.
As such, to iterate:
for (int i = 0; i < size; ++i) {
x[i] ...
}
You have a number of off-by-one errors in your code due to assuming arrays are 1..N and not 0..(N-1).
Putting it all together and cleaning up your code yields:
#include <stdio.h>
#include <stdlib.h>
void citire(int *x, size_t s)
{
for(int i=0; i < s; i++)
scanf("%d", &x[i]);
}
int produs(int *a, int* b, size_t s)
{
int produs = 0;
for(int i = 0; i < s; i++)
produs = a[i] * b[i] + produs;
return produs;
}
int main()
{
int n;
scanf("%d",&n);
int* a = calloc(n, sizeof(int));
int* b = calloc(n, sizeof(int));
citire(a, n);
citire(b, n);
// produs() returns int, not int*
int p = produs(a,b,n);
printf("%d", p);
return 0;
}
You're using pointers in places where pointers don't belong. In C passing a pointer to a single value means "this is mutable", but you don't change those values, so no pointer is necessary nor advised.
Try and use size_t as the "size of thing" type. That's what's used throughout C and it's an unsigned value as negative indexes or array lengths don't make any sense.

Pointing to arrays using void function

Sorry for that title. I really didn't know how to define this problem.
I was needed to declare integer array of N numbers and to fill it with random nums in void function. Then that array needs to be printed in main. The thing is that i am not allowed to use printf in void function so only way to print in main is to use pointers I guess. My knowledge is limited as I am beginner at pointers. Thx in advance and sorry for bad english.
Here is my code so far. When I compile it marks segmentation error.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form();
int main()
{
int N, a[100];
printf("Input index: \n");
scanf("%d", &N);
form(N, &a);
printf("Array: \n");
for (int i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr[100])
{
srand(time(NULL));
for (int i = 0; i < N; i++) {
*ptr[i] = rand() % 46;
}
There are several issues in your code.
1) Your array decalaration form() is obsolete. Use proper prototype.
2) For declaring a VLA, declare it after reading N instead of using a fixed size array.
3) An array gets converted into a pointer to its first element when passed to a function. See: What is array decaying?
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form(int, int*); /* see (1) */
int main(void) /* Standard complaint prototype for main.
If you need to pass arguments you can use argc, and argv */
{
int N;
printf("Input size: \n");
scanf("%d", &N);
int a[N]; /* see (2) */
form(N, a); /* see (3) */
printf("Array: \n");
for (int i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr) { /* Modified to match the prototype
srand(time(NULL));
for (int i = 0; i < N; i++) {
ptr[i] = rand() % 46;
}
}
So a couple things:
void form();
As Olaf was alluding to, this declaration is incorrect - you are missing the applicable parameters. Instead, it should be
void form(int N, int ptr[100]);
The main reason your program is crashing is because of the following line:
*ptr[i] = rand() % 46;
You are dereferencing the pointer at i, which is actaully giving you a number - what you want is to assign the value of the pointer at i the new random value:
ptr[i] = rand() % 46;
As related reading, see this question about passing an array in as a function parameter (basically, int ptr[] is the same thing as int * ptr)
Small modifications on your code:
1) Correction and simplification of parameter handling at function call. Just hand over "a", it's an array, so it is an address, you can use int *ptr, or int ptr[], or int ptr[100] in the formal parameter list for it. So you can use simply ptr[i] in your function.
2) Make a prototype for function from old-style declaration providing parameter list.
3) int i; declaration before the for loop - not mandatory, depends on your compiler standard
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form(int N, int *ptr);
int main()
{
int N, a[100];
printf("Input index: \n");
scanf("%d", &N);
form(N, a);
printf("Array: \n");
int i;
for (i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr)
{
srand(time(NULL));
int i;
for (i = 0; i < N; i++) {
ptr[i] = rand() % 46;
}
}

C Program, function sorting through pointers

This program is supposed to take an array, and sort it from lowest to highest value. My program won't sort any values though. I believe the error is in the selectionSort. The values i and j are present in the function, I printed them out inside the function but they are not passed into the swap function. I tried making i and j pointers but it didn't work. I just have no clue on what to do next. Any help would be appreciated.
#include <stdio.h>
#define N 5
void selectionSort(int *a, int n);
int *findLargest(int *a, int n);
void swap(int *p, int *q);
int main(void)
{
int i;
int a[N];
printf("Enter %d numbers: ", N);
for (i = 0; i < N; i++) {
scanf("%d", &a[i]);
}
selectionSort(a, N);
printf("In sorted order:");
for (i = 0; i < N; i++) {
printf(" %d", a[i]);
}
printf("\n");
return 0;
}
void selectionSort(int *a, int n)
{
int *p = a;
int i;
int j;
if (n == 1) {
return;
}
i = *(p+n-1);
j = *findLargest(a, n);
swap(&i, &j);
selectionSort(a, n - 1);
}
int *findLargest(int *a, int n)
{
int *p;
int *p_max = a;
for(p = a + 1; p < a + n - 1; p++) {
if ( *p > *p_max)
p_max = p;
}
return p_max;
}
void swap(int *p, int *q)
{
int temp = *(p-1);
*(p-1) = *q;
*q = temp;
}
The problem is in your call of swap: you swap the content of two local variables
int i;
int j;
... // Some other code, then
swap(&i, &j);
This has no effect on the original array. You should be passing p+n-1 and findLargest(a, n) directly, or store their results in pointers, not in ints:
swap(p+n-1, findLargest(a, n));
In addition, your swap is broken: rather than swapping the content of two pointers, it assumes that p points one element past the target location. This is a bad assumption to make in a general-purpose function, such as swap, and it also leads to undefined behavior in your program.
void swap(int *p, int *q) {
int temp = *p;
*p = *q;
*q = temp;
}

Nothing works - references, pointers

void load(int *n, int *x, int **arr)
{
arr = (int**)malloc(sizeof(int*)*(*n));
for(int i = *n; i >= 0; i--)
{
scanf("%d", &arr[i]);
}
}
int main()
{
int n = 0, x = 0;
int *arr;
load(&n, &x, &arr);
printf("%d", arr[1]);
return EXIT_SUCCESS;
}
The program compiles properly, but it throws windows error during the printf() in main function. Displaying just "arr" gives random big numbers. What is wrong here?
arr = (int**)malloc(sizeof(int*)*(*n));
doesn't change anything in main, it only overwrites the copy of the pointer (address of arr in main) that load receives.
What the function should do is change arr in main, for that, you have to dereference the argument,
*arr = (int*)malloc(sizeof(int)*(*n)); // cast for C++ compiler left in
to change the value of arr in main. (The object that the argument arr of load points to, that is arr in main, needs to be changed, hence you need to modify *arr in load.)
The scans should then be
scanf("%d", &(*arr)[i]);
or (equivalent)
scanf("%d", *arr + i);
#include <stdio.h>
#include <stdlib.h>
void load(int *n, int *x, int **arr)
{
int i = 0;
*arr = (int*) malloc(*n * sizeof(int));
if(!*arr) {
perror("Can not allocate memory!");
return;
}
for(i = *n; i >= 0; i--)
{
scanf("%d", *arr + i);
}
return;
}
int main()
{
int n = 0, x = 0;
int *arr;
int i;
/* You probably need to initialize n */
n = 5;
load(&n, &x, &arr);
for(i = n; i >= 0; i--)
{
printf("%d - %d\n", i, arr[i]);
}
return EXIT_SUCCESS;
}

Resources