2

I am trying this seemingly simple code to use pointers:

#include <stdio.h>

void prod_and_sum(int a, int b, int *p, int *s) {
    *p = a * b;
    *s = a + b;
}

int main() {
    int *p1, *p2;
    prod_and_sum(5, 10, p1, p2);
    printf("test");
    return 0;
}

However I do not get any output in my terminal.

It is like the program gets stuck in my function. There is no sign of the program coming out of the function, even to print a simple "test"

bobby wang
  • 202
  • 6
  • 1
    because you passed unitialized pointers to it. YOu need to make p1 and p2 point to a pair of ints – pm100 Feb 20 '23 at 22:23
  • 2
    You make pointers that don't point anywhere and then you assign data to those non-existant locations. You need to provide space to store the answers. So instead of `int *p1, *p2; prod_and_sum(5, 10, p1, p2);` try `int p1, p2; prod_and_sum(5, 10, &p1, &p2);` or if you really want pointers in main `int x, y, *p1=&x, *p2=&y; prod_and_sum(5, 10, p1, p2);` – Jerry Jeremiah Feb 20 '23 at 22:23
  • I will try that, but what exactly is going on as no error is thrown, but the program appears to terminate early. – bobby wang Feb 20 '23 at 22:24
  • 1
    Writing to uninitialized pointers is undefined behaviour. It doesn't have to give an error - and, in fact, most compilers can't detect whether there is memory there or not. – Jerry Jeremiah Feb 20 '23 at 22:27
  • "what is going on" is Undefined Behavior, which is being invoked by dereferencing uninitialized pointers `p` and `s`. – 0x5453 Feb 20 '23 at 22:27
  • @Fe2O3 It doesn't matter so much now but in the old days when there was no MMU and memory-mapped I/O, writing to unknown locations is really bad as it can actually damage hardware. – Jerry Jeremiah Feb 20 '23 at 22:29

1 Answers1

0

You pass uninitialized pointers as arguments to function prod_and_sum. Your code has undefined behavior as the function prod_and_sum dereferences these uninitialized pointers to store the sum and product*. The program can stop or continue or produce other side effects... In your case, it seems to stop silently.

The behavior is undefined, there is no point trying to understand what happens... You should just correct the problem by passing the addresses of int variables where you want the results stored:

#include <stdio.h>

void prod_and_sum(int a, int b, int *p, int *s) {
    *p = a * b;
    *s = a + b;
}

int main(void) {
    int prod, sum;
    prod_and_sum(5, 10, &prod, &sum);
    printf("sum: %d, product: %d\n", sum, prod);
    return 0;
}

Note that you can also return multiple values by making them fields of a structure that you return:

#include <stdio.h>

typedef struct prod_sum { int prod, sum; } prod_sum;

prod_sum prod_and_sum(int a, int b) {
    return (prod_sum){ a * b, a + b };
}

int main(void) {
    prod_sum res = prod_and_sum(5, 10);
    printf("sum: %d, product: %d\n", res.sum, res.prod);
    return 0;
}

* as a matter of fact, just passing the values of uninitialied pointers has undefined behavior, but attemting to dereference them is more likely to cause a visible effect such as a segmentation fault.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • I understand that you can not pass uninitialized pointers to a function now, but I still don't understand what happened, as the code seemed to just stop, and not throw an error. Does this happen in other situations with C. – bobby wang Feb 20 '23 at 22:33
  • @bobbywang - your code died, it just wasnt reported for some reason. It depends on how you were running it – pm100 Feb 20 '23 at 23:34
  • @pm100: that's not a problem, passing the address of uninitialized variable is fine and the function `prod_and_sum` sets both via the pointers from its arguments, no UB either, then both have a defined value when read and passed to `printf`. – chqrlie Feb 21 '23 at 00:40
  • @bobbywang "but I still don't understand what happened, as the code seemed to just stop, and not throw an error" That is why it is called _undefined_ behavior - there is no well-defined outcome, no deterministic behavior, no guaranteed error handling. C is a low level language, there's often nobody to hold your hand, as in higher level languages. It's the C programmers responsibility to learn which constructs that are undefined behavior and to avoid them. If the compiler or OS spotted such bugs for you then you are just lucky, they are not required or guaranteed to do so. – Lundin Feb 21 '23 at 09:56