I have begin learning pointers in C.
When I try to return pointer in a function, I'm getting segmentation fault error.
Here is the code :
#include<stdio.h>
int *sum(int *, int *);
int main(void)
{
int a, b;
int *ans = NULL;
printf("Enter number a : ");
scanf("%d", &a);
printf("Enter number b : ");
scanf("%d", &b);
ans = sum(&a, &b);
printf("Sum = %d", *ans);
return 0;
}
int *sum(int *p, int *q)
{
int *result = NULL;
*result = *p + *q;
return (result);
}
And the output :
Enter number a : 10
Enter number b : 20
Segmentation fault
Segmentation fault occurs in sum function, when result is declared as pointer. However, I am unable to figure out the reason for the same. Any help regarding this is really appreciable.
You are initing a pointer to NULL and then you are deferencing it: it is Undefined behavior
Change sum function to
int *sum(int *p, int *q)
{
int *result = malloc(sizeof(int));
// check if malloc returned a valid pointer before to dereference it
if (result != NULL)
{
*result = *p + *q;
}
return (result);
}
and add a free call to free the allocated memory.
// check if sum function allocate the pointer before to dereference it
if (ans != NULL)
{
printf("Sum = %d", *ans);
}
free(ans);
return 0;
}
You could also avoid to use pointer to return value:
#include<stdio.h>
int sum(int *, int *);
int main(void)
{
int a, b;
int ans;
printf("Enter number a : ");
scanf("%d", &a);
printf("Enter number b : ");
scanf("%d", &b);
ans = sum(&a, &b);
printf("Sum = %d\n", ans);
return 0;
}
int sum(int *p, int *q)
{
int result = *p + *q;
return (result);
}
The sum function could also be like:
int sum (int *p, int *q)
{
return (*p + *q);
}
EDIT
As #JonathanLeffler wrote in his answer you can do also:
#include<stdio.h>
void sum(int *, int *, int *);
int main(void)
{
int a, b;
int ans;
printf("Enter number a : ");
scanf("%d", &a);
printf("Enter number b : ");
scanf("%d", &b);
sum(&ans, &a, &b);
printf("Sum = %d\n", ans);
return 0;
}
void sum(int *result, int *p, int *q)
{
*result = *p + *q;
}
Allocate memory before trying to store anything, and check the return of malloc()
int *result = NULL;
result = malloc(sizeof(*result));
if(result != NULL)
*result = *p + *q;
else
printf("malloc returned error");
Also, check the return of the function in main() and exit accordingly.
int main(void)
{
.
.
.
ans = sum(&a, &b);
if(ans == NULL)
return 0;
printf("Sum = %d\n", ans);
free(ans); //free the memory then
return 0;
}
A third alternative is to declare ans as a normal int variable in the main function and pass a pointer to it to the sum function, like you do with the other two arguments. This is actually emulating call by reference.
#include<stdio.h>
int *sum(int *, int *);
int main(void)
{
int a, b;
printf("Enter number a : ");
scanf("%d", &a);
printf("Enter number b : ");
scanf("%d", &b);
int* ans = sum(&a, &b);
printf("Sum = %d", *ans);
return 0;
}
int *sum(int *p, int *q)
{
int plus = *p + *q;
int *ans = +
return ans;
}
Store the Sum in a Different variable plus and create a pointer *ans that points to that variable plus and return the pointer variable ans that holds the address of plus
Related
I am new to C and I was trying to code up a dynamic int array that lets the user type in numbers via terminal untill the user types in -1. So the user can type any amount of int's and the data is reallocated each time another valid int is input.
Sometimes it works as expected other times I get: free(): double free detected in tcache 2
Aborted (core dumped) error.
I am printing the values after every input and everything seems fine untill -1 is input. And the bug only occures every other time.
Here is my Code:
void output(int *ptr, int len){
printf("\n");
for(int i=0; i<len; i++){
printf("%d %p \n", ptr[i], ptr+i);
}
printf("\n");
}
int input(int *ptr, int *size){
int x;
printf("Insert your numbers:\n");
while(1){
scanf("%d", &x);
if(x == -1) break;
size[0]++;
// printf("Size: %d\n", size[0]);
ptr = realloc(ptr, size[0] * sizeof(int));
if(ptr == NULL) return -1;
int indexToStore = size[0]-1;
// printf("Index: %d\n", indexToStore);
ptr[indexToStore] = x;
output(ptr, size[0]);
}
return 0;
}
int main()
{
int size = 0;
int *array = (int*)malloc(sizeof(int));
if(array == NULL) return -1;
input(array, &size);
output(array, size);
input(array, &size);
output(array, size);
free(array); array = NULL;
return 0;
}
The argument ptr of the function input is a copy of what is passed and modifying that will not affect what is passed in caller.
Therefore, the change in buffer via realloc() is not saved from the 1st call of input() to the 2nd call of input() and it will lead to troubles.
You should pass a pointer to what should be modified to have functions modify caller's local things.
#include <stdio.h>
#include <stdlib.h>
void output(int *ptr, int len){
printf("\n");
for(int i=0; i<len; i++){
printf("%d %p \n", ptr[i], ptr+i);
}
printf("\n");
}
int input(int **ptr, int *size){
int x;
printf("Insert your numbers:\n");
while(1){
scanf("%d", &x);
if(x == -1) break;
size[0]++;
// printf("Size: %d\n", size[0]);
*ptr = realloc(*ptr, size[0] * sizeof(int));
if(*ptr == NULL) return -1;
int indexToStore = size[0]-1;
// printf("Index: %d\n", indexToStore);
(*ptr)[indexToStore] = x;
output(*ptr, size[0]);
}
return 0;
}
int main()
{
int size = 0;
int *array = (int*)malloc(sizeof(int));
if(array == NULL) return -1;
input(&array, &size);
output(array, size);
input(&array, &size);
output(array, size);
free(array); array = NULL;
return 0;
}
#include<stdio.h>
void add(int a,int b)
{
int c=a+b;
printf("\nSum=%d",c);
}
void hello(char *name)
{
printf("Hello %s",*name);
}
int main()
{
int a,b;
char name[20];
void (*ptr)(int,int)=&add;
void (*hello)(char*)=hello;
printf("Enter your Name:");
scanf("%s",&name);
hello(&name);
printf("Enter the two values\n");
scanf("%d%d",&a,&b);
ptr(a,b);
return 0;
}
i want to take input from user then pass it to function but i am unable to do so.
Here is what my complier shows as error: https://i.stack.imgur.com/DVYL6.png
You don't need to access the array address, it will be implicitly converted to char* when you pass it to the functions (both to scanf and hello).
I don't see the use of the functions pointers, so in order to simplify the code, I would rewrite it like this:
#include <stdio.h>
void add(int a, int b)
{
printf("Sum = %d\n", a + b);
}
void hello(char *name)
{
printf("Hello %s\n", name);
}
int main()
{
int a = 0, b = 0;
char name[20];
printf("Enter your Name:\n");
scanf("%s", name);
hello(name);
printf("Enter the two values\n");
scanf("%d%d", &a ,&b);
add(a, b);
return 0;
}
If you insist of using the pointers, this is how main should be written:
int main()
{
int a = 0, b = 0;
char name[20];
void (*add_ptr)(int, int) = &add;
void (*hello_ptr)(char *) = &hello;
printf("Enter your Name:\n");
scanf("%s", name);
hello_ptr(name);
printf("Enter the two values\n");
scanf("%d%d", &a, &b);
add_ptr(a, b);
return 0;
}
Given two numbers, n and q, I want to find two numbers, m and p, such that n=m*p and q= m+p. I compiled the code but it returned the error message every time even if the entered values are valid. Is something wrong with the loop?
edit**
input n: 100
input q: 25
still returns the error message even if m=20, p=5 works
#include <stdio.h>
int main(void){
int *mAddress = NULL;
int *pAddress = NULL;
int n;
printf("enter integer: ");
scanf("%d", &n);
int q;
printf("enter query number: ");
scanf("%d", &q);
int m;
int p;
for (m=1; m<=n; m++){
if(n%m == 0){
p = n/m;
if (m+p == q){
mAddress = &m;
pAddress = &p;
printf("The values are %d %d", m, p);
break;
}
else{
printf("could not find any numbers");
break;
}
}
}
You should not break the loop in the case you don't find it for the first time. Instead you should continue this to happen for each n%m == 0 case.
Eventually when you know that nothing hasn't been found print the error message.
I've added a bool to hold if you have found a pair or not and use it to print the error message.
#include <stdio.h>
#include <stdbool.h>
int main(void){
int *mAddress = NULL;
int *pAddress = NULL;
int n;
printf("enter integer: ");
scanf("%d", &n);
int q;
printf("enter query number: ");
scanf("%d", &q);
int m;
int p;
bool found = false;
for (m=1; m<=n; m++){
if(n%m == 0){
p = n/m;
if (m+p == q){
mAddress = &m;
pAddress = &p;
printf("The values are %d %d", m, p);
found = true;
break;
}
}
}
if (!found) {
printf("could not find any numbers");
}
}
Try it out yourself
You miss for loop bracket after if.
for (m=1; m<=n; m++){
if(n%m == 0){
p = n/m;
if (m+p == q){
mAddress = &m;
pAddress = &p;
printf("The values are %d %d", m, p);
break;
}}
I have been asked to make a code that will rearrange 3 entered integers into ascending/descending order using pointers.
I need to use the function order() to return a pointer to either function ascending3() or descending(), depending on what value of 'e' is entered.
I keep getting an error on the line specified in the readInts() function and am not sure how to fix it.
ERRORS
lvalue required as unary ‘&’ operand" -- The error for `ptr = &(order(e))`
warning: assignment makes pointer from integer without a cast -- The error for `ptr=order(e)`
Pointer code
void readInts(){
int *a,*b,*c;
char e;
int (*ptr1)(int*,int*,int*);
int result;
printf("Enter Integer 1:");
scanf("%d", a);
printf("Enter Integer 2:");
scanf("%d", b);
printf("Enter Integer 3:");
scanf("%d", c);
printf("Enter either A or D:");
scanf(" %c", &e);
ptr1 = &(order(e)); /*ERROR HERE*/
result = (*ptr1)(a,b,c);
printf("%d %d %d", a, b, c);
}
Functions
int ascending3(int* x, int* y, int* z)
{
/*removed sorting code for the sake of shortening the question*/
*x=smallest;
*y=middle;
*z=largest;
}
int descending(int* x, int* y, int* z)
{
int swap;
ascending3(x,y,z);
swap=*x;
*x=*z;
*z=swap;
}
int (*order(char e))(int*x ,int*y,int*z)
{
if(e=='a')
{
return ascending3;
}
else if(e =='d')
{
return descending;
}
return;
}
A function cannot return a function. For this reason you cannot apply the address of operator (&) to the result of your function (to retrieve an address). But a function can return a pointer to a function.
The name of a function in C (prefixed or not by the & operator) is always set as the address of the function, that's a pointer to that function.
The correct code is:
int ascending3(int *x, int *y, int *z);
int descending(int *x, int *y, int *z);
typedef int (*fn)(int *x, int *y, int *z);
fn order(char e)
{
if (e == 'a')
{
return ascending3;
}
else if (e == 'd')
{
return descending;
}
return NULL;
}
void readInts(void)
{
int *a, *b, *c;
char e;
fn ptr1;
int result;
printf("Enter Integer 1:");
scanf("%d", a);
printf("Enter Integer 2:");
scanf("%d", b);
printf("Enter Integer 3:");
scanf("%d", c);
printf("Enter either A or D:");
scanf(" %c", &e);
ptr1 = order(e);
result = (*ptr1) (a, b, c);
printf("%p %p %p", a, b, c);
}
Where I used a typedef to declare the type of our function pointer (and also 2 prototypes for the ordering functions).
If you like to have the asterisk to better show the pointer nature of our type, you can define fn as function (not a pointer to function):
typedef int (fn)(int *x, int *y, int *z);
So you can use the asterisk notation:
typedef int fn(int *x, int *y, int *z);
fn *order(char e)
{
if (e == 'a')
{
return ascending3;
}
else if (e == 'd')
{
return descending;
}
return NULL;
}
void readInts(void)
{
int *a, *b, *c;
char e;
fn *ptr1;
int result;
printf("Enter Integer 1:");
scanf("%d", a);
printf("Enter Integer 2:");
scanf("%d", b);
printf("Enter Integer 3:");
scanf("%d", c);
printf("Enter either A or D:");
scanf(" %c", &e);
ptr1 = order(e);
result = (*ptr1) (a, b, c);
printf("%p %p %p", a, b, c);
}
I want to pass a pointer to a multidimensional Array, so the value could be kept not copied. How can I do it? I also keep tracking the int count, will it work every time? The array that I need is memory. The struct has been declared before, outside the main.
struct registers
{
int data;
} registerX, registerY;
void first(int *counter, struct registers* X1, int **m)
{
int value;
printf("Enter the value for the X\n");
scanf("%d", &value);
X1->data = value;
m[*counter][1] = X1->data;
*counter = *counter++;
}
int main()
{
int memory[SIZE][2];
int count = 0;
int choice;
printf("Enter the instruction number:\n");
while(choice != 107)
{
scanf("%d", &choice);
if(choice == 101)
{
memory[count][0] = 101;
first(&count, ®isterX, &memory[count][1]);
}
The function signature should be:
void first(int *counter, struct registers* X1, int m[][2])
Or equivalently:
void first(int *counter, struct registers* X1, int (*m)[2])
The call should be:
first(&count, ®isterX, memory);
First of all, apart from what Kerrek SB said, you could replace
*counter = *counter++;
with this
(*counter)++;
EDIT: Sorry, I made a mistake trying to say what's wrong with *counter = *counter++, but I got some strange results with the sentence *pointer = *pointer++.
Second, I see that you are using registerX while it's just a type, so you could first do this.
registerX *rgx = NULL;
rgx = malloc(sizeof(registerX));
and use.
first(&count, rgx, memory);
Considering what I said above, this code worked for me.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 5
typedef struct registers {
int data;
} registerX, registerY;
void first(int *counter, struct registers *X1, int m[][2]) {
int value;
printf("Enter the value for the X: ");
scanf("%d", &value);
X1->data = value;
m[*counter][1] = X1->data;
(*counter)++;
return ;
}
int main() {
int memory[SIZE][2];
int count = 0;
int choice;
registerX *rgx = NULL;
rgx = malloc(sizeof(registerX));
printf("Enter the instruction number: ");
while(choice != 107) {
scanf("%d", &choice);
if (choice == 101) {
memory[count][0] = 101;
first(&count, rgx, memory);
printf("Number %d was stored in memory[%d][%d]\n\n", memory[count-1][1], count-1, 1);
}
printf("Enter more instructions: ");
}
return 0;
}