I'm pretty new to C coding, and pointers are something I'm having a lot of trouble with. I'm trying to write a program that takes in 2 pointers as parameters, adds the value of the first to the second, then returns the value of the first. What I've written is this:
int foo(int *g, int *h)
{
int a;
a = *g;
*h += a;
return a;
}
However, I am getting a segmentation fault error using an online compiler. I read that these are caused by rogue pointers, but I'm not sure where the error is. Can someone help?
EDIT:
I'm calling this function this way:
main()
{
int* x;
*x = 3;
int* y;
*y = 4;
int z = foo(x, y);
printf("%d", z);
}
I thought that was the way to declare a pointer, and that using (*) to dereference it was how to assign it a value. Am I incorrect?
In main you have to allocate spaces for x and y before you can use it. If x and y are not allocated spaces, they point to arbitrary memory locations. If they are outside of your program segment, you will get a segmentation fault.
main()
{
int* x=malloc(sizeof(int));
*x = 3;
int* y=malloc(sizeof(int));
*y = 4;
int z = fun(x, y);
printf("%d", z);
}
Or like this:
main()
{
int x=3,y=4;
int z = fun(&x, &y);
printf("%d", z);
}
This will cause a segfault because you are dereferencing a pointer that has not been initialized.
int *x; // declares pointer X
*x = 3; // seg fault here because x contains garbage and points certainly to
// invalid memory
Related
I have a function which returns an integer pointer type:
int* f(int a, int b){
int *result;
result = &a;
*result += b;
return result;
}
and when I call this on main:
int main(){
int a = 5;
int b = 2;
int *result = f(a,b);
printf("The result is: %d \n", *result);
return 0;
}
It gives me the correct output(in this case 7). I was under the impression that by assigning the address of the parameter a to result I would get a segmentation fault when I ran this function.
My assumption is that C treats function parameters as local in scope to the function definition. But, I see that this is not the case so why is this specific program working ?
I'm using Code::Blocks 16.01 with gcc compiler.
Just because it works on your machine doesn't mean it isn't undefined behaviour. This works by fluke, but it's invalid.
It may produce the correct result because that stack is not overwitten or otherwise mangled by the time you do something later on.
For example, if you make another function call:
#include <stdio.h>
#include <stdlib.h>
int noop(int x, int y) {
return x + y;
}
int* f(int a, int b){
int *result;
result = &a;
*result += b;
return result;
}
int main(){
int a = 5;
int b = 2;
// Do something with undefined behaviour
int *result = f(a,b);
// Do something else which uses the stack and/or the same memory
int x = 10;
int y = 11;
int z = noop(x, y);
printf("The result is: %d \n", *result);
return 0;
}
Now the output gets stomped with the definition of x which coincidentally takes the same piece of memory so the output is 10. As this is undefined behaviour, though, anything could happen, including a crash.
This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed 4 years ago.
I solved this simple question in C on my lab's system (which uses Windows). I used DevC++ to write this code and it ran on DevC++, but I cannot compile the same code on my Mac system.
Code:
#include<stdio.h>
#include<stdlib.h>
int* oddSwap(int x, int y)
{
int temp = x;
x = y * 5;
y = temp * 5;
int *k;
*k=x+y;
return k;
}
int main()
{
int x=5;
int y=3;
int *k=oddSwap(x,y);
printf("\n%d", *k);
return 0;
}
This ran on Windows (DevC++), but I'm getting this error message on running it on macOS (macOS 10.14.2).
Bus error: 10
The swap-function does not make much sense, since you swap the arguments only within the function, but the result then combines both values with commutative operator + (so why swap at all?).
And you assign a value to a pointer that does not point to a valid object: int *k; *k=x+y;. But anyway, the complete operation does not make sense to me.
Maybe you wanted something like that:
void oddSwap(int *x, int *y) {
int temp = *x;
*x = *y * 5;
*y = temp * 5;
}
int main()
{
int x=5;
int y=3;
oddSwap(&x,&y);
printf("\n%d:%d", x,y);
return 0;
}
There is an error in your code.
int* oddSwap(int x, int y)
{
int temp = x;
x = y * 5;
y = temp * 5;
int *k; // <-- the pointer 'k' is never given a value, yet you de-reference it below.
*k=x+y; // <-- this operation is invalid.
return k;
}
When you do *k = <something> you dereference the pointer.
That is, you assign <something> to the variable that k points to.
For that to be valid, you need to give k a value, i.e. make it point to something.
I get segmentation fault after executing this part of code.If i comment the first printf out,it works fine.Why does this happen?
#include <stdio.h>
int Func (int *a){
printf("%d\n",56 );
printf("a is %d\n",*a );
return 3;
}
int main(){
int N, i, Planet, *a,junk;
junk=scanf("%d", &N );
*a = N;
Planet = Func(a);
printf("%d\n", Planet);
return 0 ;
}
Inside your main function, you defined the int *a pointer variable:
int main(){
int N, i, Planet, *a,junk;
But then you dereferenced the pointer without having previously allocated any memory for it, nor setting it to point to something meaningful:
*a = N;
This results in undefined behavior.
What you probably wanted is to make a point to N?
If so, this is the correct syntax:
a = &N;
Now you can use *a to write some content into N.
P.S.
As a general rule, I'd suggest you to declare one variable per line, and initialize pointers to NULL, e.g.:
int man() {
int *a = NULL;
...
This is the code here:
#include<stdio.h>
void assign (int *a1, int *a2) {
a1 = a2;
}
int main() {
int *a; int b; int *c; int d;
b = d = 5;
a = &b;
printf("%d", *a);
assign(c, &d);
printf("\n%d", *c);
return 0;
}
It's fine when I assign pointers manually in the main() function, but the segmentation fault appears when I assign it in the function. Why is this so?
The function assign has no effect. All it's doing is performing a local assignment which has no effect on the caller. As a result, c is undefined in main and you get a segmentation fault.
In order for assign to do what you intend, you have to pass it the address of c, then do a pointer assignment in assign.
Try the following:
#include <stdio.h>
void assign (int **a1, int *a2) {
*a1 = a2;
}
int main() {
int *a; int b; int *c; int d;
b = d = 5;
a = &b;
printf("%d\n", *a);
assign(&c, &d);
printf("%d\n", *c);
return 0;
}
The output is:
5
5
I also moved the newlines to the end of the format strings, which is the normal place to put them.
c is passed by value into the function assign. This means that modifying a1 from the function will not affect c.
To get the expected results, pass c by reference, i.e, pass the address of c:
assign(&c, &d);
and make slight modifications to the function:
void assign (int **a1, int *a2) {
*a1 = a2;
}
and you are good to go! :-)
Arguments are passed by value in C, so modyfying a1 in assign() won't affect c in main().
c remains uninitialized and it has automatic storage duration, so its value is indeterminate.
Then, you used this inderminate value in printf("\n%d", *c);.
This invokes undefined behavor and the program just happened to cause segmentation fault.
I'm working with the program that scans a number in the main program. After that this program calls for a function change_number(), and as an argument gives the numbers memory address. After this program should add 3 to the number in the sub-program, print it out in the subprogram and restore that new value. However, when trying to print the number out in the subprogram change_number(), it prints out it's memory address. My understanding is that a program should return integers value when referring to the pointer with * -notation or just by inserting a variables name. Another compiler which i have tried says the following error message, and does not even compile, either with x -notation or with *pointer_x -notation:
"You are trying to initialize a variable to a value that is of the wrong type.
code.c:20: warning: assignment from incompatible pointer type".
I don't understand because my pointer is introduced as an integer, just like the integer itself. Here is the code:
#include<stdio.h>
void change_number(int *x);
int main()
{
int x;
printf("Give number x: ");
scanf("%d", &x);
printf("In main program: x = %d\n", x);
change_number(&x);
printf("In main program: x = %d\n", x);
return 0;
}
void change_number(int *x)
{
int *pointer_x;
pointer_x = &x;
x = x + 3;
printf("In sub program: x = %d\n", *pointer_x);
}
The code you've pasted should fail to compile on the line pointer_x = &x; as both x and pointer_x are type int*
Using the address-of operator on a pointer variable gives you a pointer-to-pointer - in this case, &x yields a type of int**
In addition, the line x = x + 3 advances a pointer location in memory by 3*sizeof(int) bytes, it's not modifying the original int variable.
Perhaps you intended to write *x = *x + 3 instead?
void change_number(int *x)
{
int *pointer_x;
pointer_x = x;
*x = *x + 3;
printf("In sub program: x = %d\n", *pointer_x);
}
The parameter x already contains address of the variable x from main so it have to be written as
void change_number(int *x)
{
int *pointer_x;
pointer_x = x;
*x = *x + 3;
printf("In sub program: x = %d\n", *pointer_x);
}
When you write void change_number(int *x), x is received as an int *. So, x points to int and *x is int.
So you'll need to change the following:
pointer_x = x;
*x = *x + 3;
printf("In sub program: x = %d\n", *pointer_x);
Now this prints correctly. But to restore the value, just add this line at the end:
*x = *x - 3;