Like Tree1Likes
  • 1 Post By Salem

prevent compiler warning: 'X' may be used uninitialized in this function

This is a discussion on prevent compiler warning: 'X' may be used uninitialized in this function within the C Programming forums, part of the General Programming Boards category; Hello, Thanking the people who answer in advance. =) I fixed my problem by the line from char * mac_str ...

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    16

    prevent compiler warning: 'X' may be used uninitialized in this function

    Hello,

    Thanking the people who answer in advance. =)
    I fixed my problem by the line from char * mac_str = NULL; to char mac_str[1];

    My questions:
    1) With * mac_str = NULL I get an segmentation error. Why is that? Why can't the variable be overwritten by the C function ether_ntoa_r ??

    2) my fix seems odd for some way: char mac_str[1] can only hold one character.
    why can it store my whole MAC address? I am puzzled.

    My program which these questions are related to. It's to retrieve the IP and MAC addres from my networkcard. I have to type sudo ./ipaddr eth0 to get it to work

    Code:
    // Headers needed
    #include <net/if.h>
    #include<netinet/if_ether.h>
    #include <net/if_arp.h>
    #include <netpacket/packet.h>
    #include <net/ethernet.h>     /* the L2 protocols */
    #include <asm/types.h>
    #include <linux/sockios.h>
    #include<stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <errno.h>
    #include <arpa/inet.h> //htons
    #include <sys/ioctl.h>
    #include <netinet/ether.h> //ether_ntoa_r
    
     
    int main(int argc, char *argv[])
    {
          struct ifreq ifr;
          int fd;
          memset(&ifr, 0, sizeof(ifr));
     
          
          if(argc == 1)
          {
              printf("U moet een netwerk interface naam als urgument meegeven. Bijv. eth0\n");
              exit(1);
          }
          
          // setup ifr for ioctl 
          strncpy (ifr.ifr_name, argv[1], sizeof(ifr.ifr_name) - 1);
          ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
     
          // create socket
          fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
          if ( fd == -1) {
                 fprintf(stderr," Kan socket niet aanmaken. errno code:  %s \n", strerror(errno));
                 return -1;
          }
     
          // IP adres ophalen
          if (ioctl(fd, SIOCGIFADDR, &ifr) == -1)
          {
              perror("Fout ophalen IP adres");     
              close(fd);
              return (-1);
          }
          
          // MAC adres ophalen
          if (ioctl(fd, SIOCGIFADDR, &ifr) == -1)
          {
              perror("Fout ophalen MAC adres");    
              close(fd);
              return (-1);
          }
          
          // close socket if created locally
          close(fd);
     
          printf("IP adres van %s is %s\n",argv[1],inet_ntoa(((struct sockaddr_in    
          *)&ifr.ifr_addr)->sin_addr));
          
    
         char mac_str[1];    
         
         // mac adres omzetten naar colon format
         ether_ntoa_r((const struct ether_addr *)&(ifr.ifr_hwaddr.sa_data),mac_str);
         printf("En het Mac adres is %s\n",mac_str);
          exit(0);
    }

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,551
    Well there's always the option of reading the manual.
    ether_ntoa_r(3) - Linux man page

    The functions ether_ntoa_r() and ether_aton_r() are re-entrant threadsafe versions of ether_ntoa() and ether_aton() respectively, and do not use static buffers.
    OK, so now read
    ether_aton() converts the 48-bit Ethernet host address asc from the standard hex-digits-and-colons notation into binary data in network byte order and returns a pointer to it in a statically allocated buffer, which subsequent calls will overwrite. ether_aton() returns NULL if the address is invalid.
    OK, so the output would appear to be HH:HH:HH:HH:HH:HH, which would appear to be 18 chars long (including the \0).

    > char mac_str[1];
    So how about making the length 18 instead of 1?

    > 1) With * mac_str = NULL I get an segmentation error. Why is that?
    Because you lied to the function.
    The function expect a pointer to some memory it can write to.
    You gave it NULL
    Answer - BBBBBBOOOOOOOMMMMMMM!!!!!!!!!!!!

    When you're programming in C, you need to think about how things are going to be used.
    You can't just go around declaring variables with the right type, so the compiler stops complaining. No - that's not even half the problem.
    rags_to_riches likes this.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    Registered User
    Join Date
    Aug 2008
    Location
    Belgrade, Serbia
    Posts
    163
    If you declare something as a pointer it needs to point to valid memory or to NULL, else it's a dangling pointer and dereferencing it, that is getting the value at which it points, is unexpected, often leading to a crash. To "make" valid memory, that is to allocate it, you have to call malloc(), free()ing it after it's use. In this case you need to allocate a string of 18 characters, 17 for a valid MAC address and one more for the leading '\0' which completes a null terminated string.
    Code:
    #define MAC_STR_LEN 17
    
    ...
    
    char *mac_str = malloc(sizeof(char) * (MAC_STR_LEN + 1));
    
    ... use mac_str ...
    
    free(mac_str);
    
    ...
    The compiler gives a sound warning telling you that you haven't assigned aything useful to mac_str. char mac_str[1] is an ugly hack which just might burn your computer up just like a dangling pointer if you store anything more than one character in it. The sole reason why it didn't is because you were lucky; unclaimed memory after it wasn't used by anything and it wasn't write-protected.
    Vanity of vanities, saith the Preacher, vanity of vanities; all is vanity.
    What profit hath a man of all his labour which he taketh under the sun?
    All the rivers run into the sea; yet the sea is not full; unto the place from whence the rivers come, thither they return again.
    For in much wisdom is much grief: and he that increaseth knowledge increaseth sorrow.

  4. #4
    Registered User
    Join Date
    Sep 2011
    Posts
    16
    Great! Thanks again Hauzer and Salem.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Warning C4700 uninitialized variables?
    By Quantom in forum C Programming
    Replies: 8
    Last Post: 10-16-2010, 04:56 PM
  2. Replies: 2
    Last Post: 05-19-2010, 04:39 AM
  3. Uninitialized in this function? - URGENT
    By Natta in forum C Programming
    Replies: 0
    Last Post: 09-26-2009, 12:41 AM
  4. Compiler warning and a confusing function declaration.
    By PaulBlay in forum C Programming
    Replies: 3
    Last Post: 05-20-2009, 10:18 AM
  5. Replies: 15
    Last Post: 11-11-2007, 09:40 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21