cpointerscompiler-errorsundefined-behaviorstrange-attractor

Compilation on Terminal gives off pointer warning and strange symbols


I am trying to compile and run a simple C program from my Terminal. This is my code:

#include <stdio.h>
//integers that are 3n, 3n + 1, and 3n + 2

int main(){
  int n,i,a,b,c;
  scanf("%d", &n);
  for (;n>0;n--) {
    scanf("%d", &i);
    if(n%3==0){a+=1;}
    if(n%3==1){b+=1;}
    if(n%3==2){c+=1;}
  }
  printf("%d %d %d", &a,&b,&c);
  return 0;
}

After compiling it one time it generates this warning:

warning: format specifies type 'int' but the argument has type 'int *' [-Wformat]

I don't understand why it is generating that warning because I am not assigning any pointer variables. Why is it generating it?

Also, after compiling it a couple of times more my c file is turning into symbols. I don't understand why this is happening. The name of my file is 73.c and this is how I'm compiling it on Terminal:

gcc 73.c -o 73.c

After that my file in converted to something like this (lines and lines of this):

œ˙Ì˛����Ä��������Ö� ��������H���__PAGEZERO��������������������������������������������������������(��__TEXT����������������������������������������������������__text����������__TEXT����������0�����˝�������0���������������Ä������������__stubs���������__TEXT����������.������������.��������������Ä�����������__stub_helper���__TEXT����������<�����$�������<���������������Ä������������__cstring�������__TEXT����������`������������`�����������������������������__unwind_info���__TEXT����������l�����H�������l������������������������������__eh_frame������__TEXT����������∏�����@�������∏��������������������������������Ë���__DATA��������������������������������������������������__nl_symbol_ptr�__DATA���������������������������������������������������__la_symbol_ptr�__DATA����������������������������������������������������H���__LINKEDIT������� ������������� ������`��������������������"��Ä0���� ����� �������������  �� ���@ ��0���������∏ ����� !��@���

I really don't have any idea of what's going on. I've been at it for a long time now, I know it shouldn't be that hard but I really don't know what's wrong. Somebody have any idea of what might be happening?


Solution

  • There are two major things that are wrong here:

    1. You try to print the address of variables a, b and c.
    2. You invoke Undefined Behavior, but not initializing your counters to 0.

    You want to print the integers, so change this:

    printf("%d %d %d", &a,&b,&c);
    

    to this:

    printf("%d %d %d", a, b, c);
    

    I also added some spaces, but that's just to beautify the code, to make it more readable, it won't affect the execution.

    You don't want to print the addresses! That's why you get the warning. Read more here: What is the difference between the * and the & operators in c programming?


    As achelper, mentioned, you don't compile your program as you should (but that's not the problem of the code), but it's something you should get used to. I will demonstrate what I did to compile me program (I also like to use -Wall flag, which enables all warnings):

    C02QT2UBFVH6-lm:~ gsamaras$ nano main.c
    C02QT2UBFVH6-lm:~ gsamaras$ gcc main.c -Wall -o main
    main.c:13:22: warning: format specifies type 'int' but the argument has type
          'int *' [-Wformat]
      printf("%d %d %d", &a,&b,&c);
              ~~         ^~
    main.c:13:25: warning: format specifies type 'int' but the argument has type
          'int *' [-Wformat]
      printf("%d %d %d", &a,&b,&c);
                 ~~         ^~
    main.c:13:28: warning: format specifies type 'int' but the argument has type
          'int *' [-Wformat]
      printf("%d %d %d", &a,&b,&c);
                    ~~         ^~
    main.c:11:16: warning: variable 'c' is uninitialized when used here
          [-Wuninitialized]
        if(n%3==2){c+=1;}
                   ^
    main.c:5:16: note: initialize the variable 'c' to silence this warning
      int n,i,a,b,c;
                   ^
                    = 0
    main.c:10:16: warning: variable 'b' is uninitialized when used here
          [-Wuninitialized]
        if(n%3==1){b+=1;}
                   ^
    main.c:5:14: note: initialize the variable 'b' to silence this warning
      int n,i,a,b,c;
                 ^
                  = 0
    main.c:9:16: warning: variable 'a' is uninitialized when used here
          [-Wuninitialized]
        if(n%3==0){a+=1;}
                   ^
    main.c:5:12: note: initialize the variable 'a' to silence this warning
      int n,i,a,b,c;
               ^
                = 0
    6 warnings generated.
    C02QT2UBFVH6-lm:~ gsamaras$ ./main
    2
    1
    2
    1461300256 1461300252 1461300248C02QT2UBFVH6-lm:~ gsamaras$ 
    

    In general, when in doubt, treat warnings as errors, so let's debug that code together, it will be fun. Pro-tip: Start from the first warning and resolve it. After that, the next warnings may be related, thus gone without having you really reading them!

    After applying my suggestion, all the warnings related with what you described in your question are gone. Only the uninitialized variable ones are left.

    That's easy, just initialize your variables to some initial value, like -1, if that makes sense of course.

    In your case though, you use a, b and c as counters! So you must initialize them to 0, otherwise you are starting adding your values to garbage values, and that invokes Undefined Behavior!

    So do change this:

    int n,i,a,b,c;
    

    to this:

    int n, i, a = 0, b = 0, c = 0;
    

    Without the initialization of the counters, I am getting, on my machine, now

    C02QT2UBFVH6-lm:~ gsamaras$ ./main
    2
    1
    2
    1505029184 1 1C02QT2UBFVH6-lm:~ gsamaras$
    

    You see that printf() gives me some garbage, while after initializing my counters to 0, I got:

    C02QT2UBFVH6-lm:~ gsamaras$ ./main
    2
    1
    2
    0 1 1C02QT2UBFVH6-lm:~ gsamaras$