Thread: Global Variables

  1. #16
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Code:
       initiate(argv[1]);
    You're just passing one argument and the function is expecting two.
    Also as outlined above, initiate needs to take a char** so it can initialize the packet var in main.

  2. #17
    Registered User
    Join Date
    Aug 2006
    Posts
    127
    So

    Code:
     initiate(argv[2]);
    ?

    I don't see how that would fix the argument errors?

  3. #18
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No.
    Code:
    initiate(argv[1], &packet);
    It expects TWO arguments. And you'll have to pass a pointer to your pointer (packet) in main so initiate can initialize your variable in main.

  4. #19
    Registered User
    Join Date
    Aug 2006
    Posts
    127
    "assign2revise.c", line 50: warning: argument #2 is incompatible with prototype:
    prototype: pointer to char : "assign2revise.c", line 28
    argument : pointer to pointer to char
    "assign2revise.c", line 64: prototype mismatch: 0 args passed, 1 expected
    "assign2revise.c", line 215: prototype mismatch: 0 args passed, 1 expected
    "assign2revise.c", line 234: prototype mismatch: 0 args passed, 1 expected

    Ok so I changed that but it hasn't fixed any of the errors, just given me others.

  5. #20
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, you need to change the type of packet to char **packet, and use *packet = malloc(...);

    I'm really just telling you how it should be done, I should give you hints so that you learn, rather than just tell you the answer.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #21
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    1. Your initiate function also attempts to open the file indicated by the global FILE pointer fp. To further comply with the restrictions against global variables, the FILE pointer must be declared in main and passed into your initiate function.

    2. Furthermore, the function also initializes the head_msg and head_pkt variables. These are currently globals in your code so the declarations of these must also be moved into main; the initializations of these are simple enough (just assign to NULL) that you can probably skip having to pass them to the initialize function for such a basic assignment and simply do that where you declare them in main. This will avoid having to pass two more arguments into the function.

    3. You should avoid casting the return value of malloc in C; in C++ you'd have to but then again you'd be using new instead of malloc.

    4. sizeof(char) is guaranteed to be 1 (I believe). Therefore malloc(2000*sizeof(char)) is the same as malloc(2000)... much simpler.


    Summing all that up and putting it into practice...
    Code:
    void initiate(char *filename, char **packet, FILE **fp);
    
    ...
    
    int main(int argc,  char **argv)
    {
        char *packet;
        FILE *fp;
        struct messagenode *head_msg = NULL;
        struct packetnode *head_pkt = NULL;
    
        if(argc != 2)
        {
            printf("Please provide one message data file\n");
            return -1;
        }
        initiate(argv[1],&packet,&fp);
    
    ...
    
    
    void initiate(char *filename, char **packet, FILE **fp)
    {
        *fp = fopen(filename, "r");
        if(*fp == NULL)
        {
            printf("Unable to open %s\n", filename);
            exit(0);
        }
        *packet = malloc(2000);
    }
    Similar considerations must be made for all the other global variables you currently have. The numbers and types of arguments of all or at least many of your functions will have to change. When calling them you must make sure you pass the correct numbers of arguments to them and also make sure the types agree with what is being passed in.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  7. #22
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    hk makes a good example.

    I amde the point earlier that everal functions are using global variables when local ones would make at least as much sense. This saves some work on passing arguments.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #23
    Registered User
    Join Date
    Aug 2006
    Posts
    127
    So I have moved them all into local variables but now when I go to run the code I get Segmentation fault errors and Bus fault errors... Any ideas what these are and/or what would cause them?

  9. #24
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Taka View Post
    So I have moved them all into local variables but now when I go to run the code I get Segmentation fault errors and Bus fault errors... Any ideas what these are and/or what would cause them?
    Yes, you haven't make the modification correctly, and you are [probably] using variables that aren't initialized or set correctly.

    Edit: I suppose I should expand on that: A segmentation fault is what you get when you access memory that isn't valid for your process, such as a NULL pointer or "any random address" that hasn't been assigned through malloc() or taking the address of a valid memory location. A bus fault, I believe is when you try to access an unaligned address, e.g. an integer which is four bytes on an address that isn't aligned to 4 bytes.

    --
    Mats
    Last edited by matsp; 10-30-2007 at 06:00 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #25
    Registered User
    Join Date
    Aug 2006
    Posts
    127
    Ok thanks, I'll run through it again.

  11. #26
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    If you have a debugger (e.g. gdb) it is fairly easy to debug crashes with segfault and such, because you can just look at the stack-trace and see where your app crashed, how you got there and what the variables are. It is usually [with some experience] quite easy to tell what went wrong.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #27
    Registered User
    Join Date
    Aug 2006
    Posts
    127
    I've run through it a bunch of times and I'm probably looking at it too much but I can't find whats causing the Segmentation Fault Error.

    Any help would be great.

    EDIT: Sorry when I tried to use gdb it comes up (no debugging symbols found)

    Code:
    #include<stdio.h>
    #include<string.h>
    #include<unistd.h>
    #include<stdlib.h>
    
    struct pktnode
    {
       int pkt_id;
       char *message;
       struct pktnode *next;
    };
    
    struct messagenode
    {
       int msg_id;
       int prefix_len;
       char id_prefix[3];
       struct pktnode *pkthead;
       struct messagenode *next;
    };
    
    #define DELIM ":"
    
    void initiate(char *filename, char *packet, FILE *fp);
    void populateInList(char *packet);
    struct messagenode *getMsgNode();
    struct pktnode *getPktNode();
    struct messagenode *search_msg(int msg_id);
    struct pktnode *search_pkt(int pkt_id);
    void getPacketInfo(char *packet,  int *msg_id, int *pkt_id, 
       char *message, int *prefix_len_msg);
    void display();
    void cleanUpAll(char *packet, FILE *fp);
    void sortMsg();
    int getlen(char *arg);
    
    int main(int argc,  char **argv)
    {
       FILE *fp;
       char *packet;
       
       if(argc != 2)
       {
          printf("Please provide one message data file\n");
          return -1;
       }
       initiate(argv[1], packet, fp);
    
       while(1)
       {
          fgets(packet, 2000, fp);
    
          if(packet == NULL || !strcmp(packet, "END\n")|| !strcmp(packet, "END"))
             break;
          populateInList(packet);
       }
       sortMsg();
    
       display();
       
       cleanUpAll(packet, fp);
       return 0;
    }
    
    void initiate(char *filename, char *packet, FILE *fp)
    {
       struct messagenode *head_msg;
       struct pktnode  *head_pkt;
    
       head_msg = NULL;
       head_pkt = NULL;
    
       fp = fopen(filename, "r");
       if(fp == NULL)
       {
          printf("Unable to open &#37;s\n", filename);
          exit(0);
       }
       packet = (char *)malloc(2000 * sizeof(char));
    }
    
    void populateInList(char *packet)
    {
       int msg_id, pkt_id, prefix_len_msg;
       char *message;
       struct messagenode *tmp_message,  *loc;
       struct pktnode *tmp_packet,  *loc_pkt;
       struct pktnode  *head_pkt;
       struct messagenode *head_msg, *save_msg, *current_msg;
    
       message = (char *)malloc(1500*sizeof(char));
       
       getPacketInfo(packet, &msg_id, &pkt_id, message, &prefix_len_msg);
       
       if((loc = search_msg(msg_id)) != NULL)
       {
          tmp_packet = getPktNode();
          tmp_packet->pkt_id = pkt_id;
          tmp_packet->message = message;
    
          head_pkt = loc->pkthead;
    
          if(head_pkt == NULL)
             head_pkt = tmp_packet;
          else 
          {
             loc_pkt = search_pkt(pkt_id);
    
             if(loc_pkt == head_pkt && pkt_id < loc_pkt->pkt_id)
             {
                tmp_packet->next = head_pkt;
                head_pkt = tmp_packet;
                loc->pkthead = head_pkt;
             }  
             else 
             {
                tmp_packet->next = loc_pkt->next;
                loc_pkt->next = tmp_packet;
             }
          }
       }
       else
       {
          /* Second condition: loc==NULL i.e. Message entry not found */
          tmp_message = getMsgNode();
          tmp_message->msg_id = msg_id;
          tmp_message->prefix_len = prefix_len_msg;
          tmp_message->next = NULL;
          tmp_message->pkthead = getPktNode();
          tmp_message->pkthead->pkt_id = pkt_id;
          tmp_message->pkthead->message = message;
          
          if(head_msg == NULL)
             head_msg = tmp_message;
          else 
          {
             current_msg = head_msg;
             while(current_msg != NULL)
             {
                save_msg = current_msg;
                current_msg = current_msg->next;
             }
             save_msg->next = tmp_message;
          }
       }
    }
    
    struct messagenode * getMsgNode()
    {
       struct messagenode *tmp;
    
       tmp = (struct messagenode *)malloc(sizeof(struct messagenode));
       tmp->pkthead = NULL;
       return tmp;
    }
    
    struct pktnode * getPktNode()
    {
       struct pktnode *tmp;
    
       tmp = (struct pktnode *)malloc(sizeof(struct pktnode));
       tmp->next = NULL;
       return tmp;
    }
    
    /* Function to search a message node in message linked list */
    
    struct messagenode *search_msg(int msg_id)
    {
       struct messagenode *head_msg, *current_msg;
    
       current_msg = head_msg;
       if(head_msg == NULL)
          return NULL;
       else 
       {
          while((current_msg != NULL) && (current_msg->msg_id != msg_id))
             current_msg = current_msg->next;
          if(current_msg == NULL)
             return NULL;
          if(current_msg->msg_id == msg_id)
             return current_msg;
          else
             return NULL;
       }
    }
     
    /* Function to search a packet node in packet linked list */
    
    struct pktnode *search_pkt(int pkt_id)
    {
       struct pktnode  *head_pkt, *save_pkt, *current_pkt;
    
       current_pkt = head_pkt;
       save_pkt = current_pkt;
    
       while((current_pkt != NULL) && (pkt_id > current_pkt->pkt_id))
       {
          save_pkt = current_pkt;
          current_pkt = current_pkt->next;
       }
       return save_pkt;
    }
    
    /* Function to get packet info from packet string*/
    
    void getPacketInfo(char *packet,  int *msg_id, int *pkt_id, 
       char *message, int *prefix_len_msg)
    {
       char *tokenPtr = NULL;
       char array[10][1500];
       char bkp_packet[2000];
       FILE *fp;
       int counter = 0, i=0;
       
       strcpy(bkp_packet, packet);
    
       tokenPtr = (char *)strtok(packet, DELIM);
       if(tokenPtr == NULL)
       {
          printf("Fatal Error1 !! Invalid Message Format\n");
          cleanUpAll(packet, fp);
          exit(0);
       }
       strcpy(array[0], tokenPtr);
       counter++;
    
       while(1)
       {
          tokenPtr = (char *)strtok(NULL, DELIM);
          if(tokenPtr == NULL)
             break;
          strcpy(array[counter], tokenPtr);
          if(counter>2)
             strcat(array[counter-1], ":");
          counter++;
       }
       if(counter < 3)
       {
          printf("Fatal Error3 !! Invalid Message Format\n");
          cleanUpAll(packet, fp);
          exit(0);
       }
       *prefix_len_msg = getlen(array[0]);
       *msg_id = atoi(array[0]);
       *pkt_id = atoi(array[1]);
       for(i=2; i<counter; i++)
       {
          strcat(message, array[i]);
       }
    }
    
    int getlen(char *arg)
    {
       int n=0;
       char ch;
    
       while(1)
       {
          ch = arg[n];
          if(ch != '0')
             break;
          n++;
       }
       return n;
    }
    
    /* Move through formulated linked list and display the content.*/
    
    void display(FILE *fp)
    {
       struct messagenode *head_msg, *current_msg;
       struct pktnode  *current_pkt;
       char display_string[2000];
       char prefix[3];
       int i;
    
       current_msg = head_msg;
       while(current_msg != NULL)
       {
          for(i=0; i<current_msg->prefix_len; i++)
             prefix[i]= '0';
          prefix[i]='\0';
          sprintf(display_string, "Message %s%d\n", prefix, 
             current_msg->msg_id);
          current_pkt = current_msg->pkthead;
          while(current_pkt != NULL)
          {
             strcat(display_string, current_pkt->message);
             current_pkt = current_pkt->next;
          }
          current_msg = current_msg->next;
          printf("%s\n", display_string);
       }
    }
    
    /* Move through linked list and deallocate it. Close file pointer also */
    
    void cleanUpAll(char *packet, FILE *fp)
    {
       struct messagenode *head_msg, *current_msg;
       struct pktnode  *head_pkt, *current_pkt;
    
       fclose(fp);
       free(packet);
    
       while(head_msg != NULL)
       {
          head_pkt = head_msg->pkthead;
          while(head_pkt != NULL)
          {
             free(head_pkt->message);
             current_pkt = head_pkt->next;
             free(head_pkt);
             head_pkt = current_pkt;
          }
          current_msg = head_msg->next;
          free(head_msg);
          head_msg = current_msg;
       }
    }
    
    /* Sort the message linked list*/
    
    void sortMsg()
    {
       int tmp_id, tmp_len;
       struct messagenode *head_msg, *save_msg, *current_msg;
       struct pktnode *tmp_head;
       
       if(head_msg == NULL)
          return;
       else 
       {
          for(current_msg = head_msg; (current_msg != NULL); 
             current_msg = current_msg->next)
          {
             for(save_msg = current_msg->next; 
                (save_msg != NULL); save_msg = save_msg->next)
             {
                if(current_msg->msg_id > save_msg->msg_id)
                {
                   tmp_id = save_msg->msg_id;
                   tmp_head = save_msg->pkthead;
                   tmp_len = save_msg->prefix_len;
    
                   save_msg->msg_id = current_msg->msg_id;
                   save_msg->pkthead = current_msg->pkthead;
                   save_msg->prefix_len = current_msg->prefix_len;
    
                   current_msg->msg_id = tmp_id;
                   current_msg->pkthead = tmp_head;
                   current_msg->prefix_len = tmp_len;
                }
             }
          }
       }
    }
    Last edited by Taka; 10-30-2007 at 04:05 PM.

  13. #28
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    If you add "-g" [and perhaps -O0] to your gcc compiler, it should give you debug symbols [and no optimization, so it's easier to follow what is actually going on].

    Edit: Did you even read post #21 above?

    --
    Mats
    Last edited by matsp; 10-31-2007 at 04:50 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #29
    Registered User
    Join Date
    Aug 2006
    Posts
    127
    I did read it and when I did it my program wouldn't compile with the below errors:

    Checking that submission compiles
    cc1: warnings being treated as errors
    assign2.c: In function 'main':
    assign2.c:42: warning: unused variable 'head_pkt'
    assign2.c:41: warning: unused variable 'head_msg'
    ERROR - Failed to compile with the following command
    gcc -Wall -Werror -Wmissing-declarations -pedantic-errors -ansi -o a.out -lm ass
    ign2.c

  15. #30
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    I'm guessing (not 100&#37; sure) that the "-pedantic-errors" is what's preventing that from compiling. Those are all warnings and not serious errors however that flag tells the compiler to treat warnings as errors which prevents the code from being compiled.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 08-06-2008, 09:59 AM
  2. scope of global variables
    By laertius in forum C++ Programming
    Replies: 4
    Last Post: 10-15-2006, 01:59 AM
  3. global variables - okay sometimes...?
    By MadHatter in forum C++ Programming
    Replies: 21
    Last Post: 01-21-2003, 04:23 PM
  4. global variables
    By rdnjr in forum Linux Programming
    Replies: 0
    Last Post: 01-07-2003, 10:28 AM
  5. Global variables? Bad! Yes, but to what extent?
    By Boksha in forum C++ Programming
    Replies: 6
    Last Post: 05-26-2002, 04:37 PM