Reputation: 11
Using pointers, GCD and LCM are solved using a single function and pointer. I'm not used to pointers yet. Anyway, I wrote the code below. However, errors such as terminated with exit code: 3221225477 continue to appear. According to a search on the Internet, the exit code above is due to incorrect memory references. But I don't know which part is wrong.
#include <stdio.h>
void gcdlcm(int a, int b, int* p_gcd, int* p_lcm){
int tmp, n, result_gcd, result_lcm;
int gcd_a, gcd_b;
p_gcd = &result_gcd;
p_lcm = &result_lcm;
if(a < b){
tmp = a;
a = b;
b = tmp;
}
gcd_a = a;
gcd_b = b;
if(gcd_b == 0){
result_gcd = 0;
}
while (gcd_b != 0)
{
n = gcd_a % gcd_b;
gcd_a = gcd_b;
gcd_b = n;
}
result_gcd = gcd_a;
printf("result_gcd = %d\n", result_gcd);
result_lcm = a * b / result_gcd;
printf("result_lcm = %d\n", result_lcm);
}
int main(){
int x, y;
int *p_gcd, *p_lcm;
scanf("%d %d", &x, &y);
gcdlcm(x, y, p_gcd, p_lcm);
printf("%d %d", *p_gcd, *p_lcm);
return 0;
}
Upvotes: 0
Views: 519
Reputation: 310980
You declared uninitialized pointers:
int *p_gcd, *p_lcm;
that have indeterminate values.
These pointers are passed by you to a function by value:
gcdlcm(x, y, p_gcd, p_lcm);
That is the function deals with copies of the values of the pointers p_gcd
and p_lcm
. So changing the copies do not affect the original pointers.
As a result dereferencing these initializing pointers in the statement:
printf("%d %d", *p_gcd, *p_lcm);
results in undefined behavior.
If you want to change the original pointers in the function you need to pass them by reference.
In C passing by reference means passing objects indirectly through pointers to them. So dereferencing the pointers you will get a direct access to the objects.
For example:
void gcdlcm(int a, int b, int **p_gcd, int **p_lcm){
int tmp, n, result_gcd, result_lcm;
int gcd_a, gcd_b;
*p_gcd = &result_gcd;
*p_lcm = &result_lcm;
//...
and in main:
gcdlcm(x, y, &p_gcd, &p_lcm);
Upvotes: 0
Reputation: 134
the error is in this line printf("%d %d", *p_gcd, *p_lcm);
. and the reason is that both will point to some random data.
This happens because your function will copy these values. p_gcd
and p_lcm
from your function are copies of the values in main. so when you set them, just the copies are modified to point to the variable, not the actual values. you should add a &
or another * there, but even doing that will give you an error. because you try to return addresses of result_gcd
and result_lcm
which are local to your function.. and their addresses are invalid after the function ends
the best way around this would be (in my opinion) to return both values in a struct:
struct Result {
int gdc;
int lcm
};
struct Result gcdlcm(int a, int b){
//...
struct Result r;
r.gdc = result_gcd;
r.lcm = result_lcm;
return r;
}
if you dont like the solution, you can use pass pointers to variables in main and set them up in the function:
void gcdlcm(int a, int b, int* p_gcd, int* p_lcm){
int tmp, n, result_gcd, result_lcm;
int gcd_a, gcd_b;
if(a < b){
tmp = a;
a = b;
b = tmp;
}
gcd_a = a;
gcd_b = b;
if(gcd_b == 0){
result_gcd = 0;
}
while (gcd_b != 0)
{
n = gcd_a % gcd_b;
gcd_a = gcd_b;
gcd_b = n;
}
result_gcd = gcd_a;
printf("result_gcd = %d\n", result_gcd);
result_lcm = a * b / result_gcd;
printf("result_lcm = %d\n", result_lcm);
*p_gcd = result_gcd;
*p_lcm = result_lcm;
}
int main(){
int x, y;
int p_gcd, p_lcm;
scanf("%d %d", &x, &y);
gcdlcm(x, y, &p_gcd, &p_lcm);
printf("%d %d", p_gcd, p_lcm);
return 0;
}
Upvotes: 0
Reputation: 29126
Here:
p_gcd = &result_gcd;
you change the local variable p_gcd
. This wil not affect the p_gcd
in main
, which after returning from gcdlcm
has the same undefined value as before. Dereferencing it leads to your exception.
I you want to pass arguments as pointers so that your function can fill in the correct data, you must create variables to hold the data, then pass pointers to them with the address-of operator &
:
int gcd, lcm;
scanf("%d %d", &x, &y);
gcdlcm(x, y, &gcd, &lcm);
(By the way, that's exactly the same how the scanf
function one line above your call works.)
In your function, assign the result to what the pointer points to:
*p_gcd = gcd_a;
This modifies the variable gcd
in main
via the pointer p_gcd
. Now, after returning from gcdlcm
, gcd
has the desired value.
Upvotes: 2