0

I have an array of int *arr[3]; and its elements are initialized like this :

sides[0] = &a;
sides[1] = &b;
sides[2] = &c;

Where a=b=5 and c=10. Now when i try to cast the type of the value (from int to double) of the contents of the memory address that each pointer is pointing at, the 3rd value shows up always as 0. Do you know why?

Here's what i'm doing:

double a,b,c;
a = (double) *sides[0];
b = (double) *sides[1];
c = (double) *sides[2];
printf("%lf %lf %lf",a,b,c);

The output i get is:

5.0000 5.0000 0.0000

Here's the full code:

    #include <stdio.h>
#include <math.h>

void populateSides(int *[3]);
void calculateTriangleType(int *[3]);

/*
* Function populateSides: Has 1 arg
* 1st arg: an array of int *.
* This function stores the 3 sides of a triangle 
* given by the user into the sides array.
*/
void populateSides(int *sides[]) {
    int i,a,b,c;
    scanf(" %d",&a);
    scanf(" %d",&b);
    scanf(" %d",&c);
    while((c <= b) || (c <= a)) {
        scanf(" %d",&c);
    }
    sides[0] = &a;
    sides[1] = &b;
    sides[2] = &c;
}

/*
*/
void calculateTriangleType(int *sides[]) {
    double a,b,c;
    a = (double) *sides[0];
    b = (double) *sides[1];
    c = (double) *sides[2];
    printf("%lf %lf %lf",a,b,c);

}

int main(void) { // Stelios Papamichail 4020
    int *sides[3]; // stores each side of a triangle ( >0)
    populateSides(sides);
    calculateTriangleType(sides);
    return 0;
}
Stelios Papamichail
  • 955
  • 2
  • 19
  • 57
  • 4
    Please provide a [mcve]. The lifetime of the variables is important as well – UnholySheep Nov 14 '18 at 15:05
  • @Swordfish i thought about that but if that was the case, wouldn't i be experiencing undefined behavior? In this case it's always just the 3rd element that has a value of 0.0 whereas the other 2 are always ok – Stelios Papamichail Nov 14 '18 at 15:08
  • Is the `a` in `sides[0] = &a;` the same as in `double a,...`? – mch Nov 14 '18 at 15:08
  • @TypeIA Yes, right. – Swordfish Nov 14 '18 at 15:08
  • @mch yes, let me add some more of my code – Stelios Papamichail Nov 14 '18 at 15:09
  • 7
    The variables in `populateSides` are local and go out of scope when the function returns. You have dangling pointers in `sides` -> dereferencing them invokes *undefined behavior* – UnholySheep Nov 14 '18 at 15:10
  • 1
    Why not just use `int sides[3];`? You won't have these issues. – 001 Nov 14 '18 at 15:11
  • @JohnnyMopp for some reason our teacher wanted us to use an array of pointers to int... – Stelios Papamichail Nov 14 '18 at 15:14
  • You can make the variables a, b, c `static` and it will solve the bug. But it's still a very ugly way to write a program. – Lundin Nov 14 '18 at 15:15
  • Unrelated to your problem, but there is no need for the leading space in the `scanf()` format strings. `%d` already ignores leading whitespace characters; the only `scanf()` directives that do not ignore leading whitespace characters are `%c`, `%n`, and `%[]`. Also, and more importantly, you should be checking the value returned by the calls to `scanf()` to verify that input is as expected. – ad absurdum Nov 14 '18 at 15:16
  • `sides[0] = &a;` is assigning the address of a local variable to `sides[0]`. That cannot be correct. – luci88filter Nov 14 '18 at 15:16
  • Absolutely do _not_ make the variables `static`. You may need to seek clarification from your teacher, as the method currently shown is _not_ the best way to accomplish this. It would be much better to pass in an array of `int`s (not an array of pointers) and directly store the `scanf()` conversion output in that array. – TypeIA Nov 14 '18 at 15:16
  • If you are forced to use an array of pointers (please ask your teacher again maybe you misunderstood) you needed to allocate memory for every entry in `sides` first with `malloc` and then just `scanf` the values directly into the array. – Yastanub Nov 14 '18 at 15:18
  • @TypeIA multiple students did but he was adamant that we should use `int *[]` instead of a simple `int []` . Can't tell why to be honest – Stelios Papamichail Nov 14 '18 at 15:19
  • @Yastanub i tried doing that when i first got started but was lost on how to cast the `int` èach pointer was pointing at , to a `double`. Should i go back to trying and figure out that? – Stelios Papamichail Nov 14 '18 at 15:20
  • Just as you already did. The only difference would be to not assign the addresses of the local variables, but rather allocate the memory yourself with `malloc` – Yastanub Nov 14 '18 at 15:23
  • @Yastanub my only concern on that would be that we were taught about `malloc` after we were given the exercises so i don't think we are "allowed" to use it. Can't it be done without it? – Stelios Papamichail Nov 14 '18 at 15:24
  • @Yastanub Can't the OP do `scanf(" %d", sides[0]);` since `sides[0]` is an address ? – luci88filter Nov 14 '18 at 15:26
  • @luci88filter It needs to be initialized to point to valid memory. Therefore you need `malloc`. – Osiris Nov 14 '18 at 15:28
  • @Osiris -- "Therefore you need `malloc`": Not necessarily. A simple `int a, b, c; sides[0] = &a; sides[1] = &b; sides[2] = &c;` in `main()` would suffice. Or `int nums[3]; for (size_t i = 0; i < 3; i++) { sides[i] = &nums[i]; }` – ad absurdum Nov 14 '18 at 15:34
  • Here's 3 different ways: using `static`, using local vars in `main`, and using `malloc`. https://ideone.com/DSGuJb – 001 Nov 14 '18 at 15:36
  • @DavidBowling I was referring to the comment that suggested to use `malloc` and explained why you can't just write inside `sides[0]` just because it is an address. Of course there are other possibilities to point to valid memory. – Osiris Nov 14 '18 at 15:41

0 Answers0