Pointer within a Struct

This is a discussion on Pointer within a Struct within the C Programming forums, part of the General Programming Boards category; I have a struct Code: typedef struct TEST { int * Flag; int Value; } TEST; TEST my_struct; How do ...

  1. #1
    Registered User
    Join Date
    Feb 2009
    Posts
    278

    Pointer within a Struct

    I have a struct

    Code:
    typedef struct TEST {
      int * Flag;
      int Value;
    } TEST;
    
    TEST my_struct;
    How do I properly set the value of Flag? If I had a int * ptr; not in a struct I would use *ptr = 3; Does *mystruct.Flag = 3; work? It doesn't seem to be...

    Thanks

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,112
    Quote Originally Posted by Bladactania
    Does *mystruct.Flag = 3; work?
    It should, assuming that the pointer already points to an int that exists.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Feb 2009
    Posts
    278
    Ok. Now something else... I have a global variable my_struct like above. In a function...

    Code:
    void set_flags(int * new_flag) {
      my_struct.Flag = new_flag;
    }
    
    int main() {
      int new_flag;
      set_flags((int *) &new_flag);
      new_flag = 0;
      new_flag = 1;
    }
    The last 2 statements in main should also change the value of my_struct.Flag. Is this correct?
    Last edited by Bladactania; 04-03-2009 at 11:26 AM. Reason: var name

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,112
    What is new_flag in the main function?
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Feb 2009
    Posts
    278
    wrong name... fixed above.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,112
    Ah.

    Quote Originally Posted by Bladactania
    The last 2 statements in main should also change the value of my_struct.Flag. Is this correct?
    No, but it will change the value of what my_struct.Flag points to.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Feb 2009
    Posts
    278
    Actually what I want is whenever I change the value pointed to by mystruct.Flag, the value of new_flag changes...

    Code:
    void set_flags(int * new_flag) {
      my_struct.Flag = new_flag;
      *my_struct.Flag = 123;
    }
    
    int main() {
      int new_flag = 0;
      set_flags((int *) &new_flag);
      
      if (new_flag == 123) printf("It worked!");
      else printf("It didn't work!");
    
    return 0;
    }

  8. #8
    CSharpener vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,484
    why do you need a cast in the call to set_flags?
    The first 90% of a project takes 90% of the time,
    the last 10% takes the other 90% of the time.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,112
    Quote Originally Posted by Bladactania
    Actually what I want is whenever I change the value pointed to by mystruct.Flag, the value of new_flag changes..
    Since my_struct.Flag points to new_flag, that should happen.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Feb 2009
    Posts
    278
    What I'm ultimately doing here is writing a serial port driver... Here is the code I have... Please note that the bottom part of the code was provided for testing purposes... I've commented so you can see it...

    Code:
    #include <dos.h>
    #include <ctype.h>
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    
    #define BUFLEN 100
    #define REPEAT_COUNT 5
    #define	TIME_LIMIT 5
    
    #define FALSE   0
    #define TRUE    1
    
    #define IDLE    0
    #define READING 1
    #define WRITING 2
    
    #define EVENT_IN_PROGRESS 0
    #define EVENT_COMPLETE    1
    
    // Serial Port Setup Addresses for COM1
    #define COM1_BASE            0x3F8          // Base address for COM1 Port
    #define COM1_BUFFERS         COM1_BASE + 0  // Transmitter Holding Buffer (W) and Receiver Buffer (R) when DLAB=0
    #define COM1_DL_LSB          COM1_BASE + 0  // Divisor Latch (Baud Rate) Least Sig. Byte (R/W) when DLAB=1
    #define COM1_INTERRUPT       COM1_BASE + 1  // Interrupt Enable (R/W) when DLAB=0
    #define COM1_DL_MSB          COM1_BASE + 1  // Divisor Latch Baud Rate Most Sig. Byte (R/W) when DLAB=1
    #define COM1_INT_ID          COM1_BASE + 2  // Interrupt Identification (R)
    #define COM1_LINE_CONTROL    COM1_BASE + 3  // Line Control Register (R/W)
    #define COM1_MODEM_CONTROL   COM1_BASE + 4  // Modem Control Register (R/W)
    #define COM1_LINE_STATUS     COM1_BASE + 5  // Line Status Register (R) (bit 7 is DLAB bit)
    #define COM1_MODEM_STATUS    COM1_BASE + 6  // Modem Status Register (R)
    #define COM1_INTVECT         0x0C           // COM1's IRQ Base Address
    
    #define PIC_MASK             0x21           // Programmable Interrupt Controller Mask Register
    #define PIC_COMMAND          0x20           // Programmable Interrupt Controller Command Register
    #define PIC_EOI              0x20           // End of Interrupt Code
    
    #define RING_BUFFER_SIZE     1025           // Ring Buffer Size in Bytes (# of Chars)
    
    // com_open Return Values
    #define COM_OPEN_SUCCESS     0
    #define COM_OPEN_INV_FLAG    -101
    #define COM_OPEN_INV_BAUD    -102
    #define COM_OPEN_PORT_OPEN   -103
    
    // com_close Return Values
    #define COM_CLOSE_SUCCESS    0
    #define COM_CLOSE_NOT_OPEN   -201
    
    // com_write Return Values
    #define COM_WRITE_SUCCESS    0
    #define COM_WRITE_NOT_OPEN   -401
    #define COM_WRITE_INV_BUFF   -402
    #define COM_WRITE_INV_COUNT  -403
    #define COM_WRITE_DEV_BUSY   -404
    
    // com_read Return Values
    #define COM_READ_SUCCESS    0
    #define COM_READ_NOT_OPEN   -301
    #define COM_READ_INV_BUFF   -302
    #define COM_READ_INV_COUNT  -303
    #define COM_READ_DEV_BUSY   -304
    
    // Device Control Block
    typedef struct DCB {
    	int  Is_Open;
    	int  *Event_Flag;
    	int  Status;
      char *In_Buffer;
      int  *In_Count;
      int  *In_Done;
      char *Out_Buffer;
      int  *Out_Count;
      int  *Out_Done;
      char Ring_Buffer[RING_BUFFER_SIZE];
      int  Ring_Buffer_In;
      int  Ring_Buffer_Out;
      int  Ring_Buffer_Count;
    } DCB; 
    
    // Function Prototypes
    void Output_Interrupt(void);
    
    /* com_open: open the com port */
    /*	RETURNS: error code, or zero if ok */
    int com_open (int *ef_p, /* ptr to event flag */
    		int baud_rate /* requested speed */
    	);
    
    /* com_close: close the com port */
    /*	RETURNS: error code, or zero if ok */
    int com_close (void);
    
    /* com_read: begin block input */
    /*	RETURNS: error code, or zero if ok */
    int com_read (char *buf_p, /* ptr to buffer */
    		int *count_p /* ptr to max. no. of chars to read */
    	);
    
    /* com_write: begin block output */
    /*	RETURNS: error code, or zero if ok */
    int com_write (char *buf_p, /* ptr to buffer */
    		int *count_p /* ptr to no. of chars to write */
    	);
    
    
    void abort_test(void);
    
    
    
    
    DCB Com1;
    
    // Begin COM1 Interrupt Setup Functions
    void interrupt (*old_COM1_Interrupt)();
    
    void interrupt COM1_Interrupt() {
      if (Com1.Is_Open) {
        switch (inportb(COM1_INT_ID) & 0x07) {
          case 0 : // Modem Status Interrupt
            inportb(COM1_MODEM_STATUS);
            break;
          case 1 : // Output Interrupt
            Output_Interrupt();
            break;
          case 2 : // Input Interrupt
            //Input_Interrupt();
            break;
          case 3 : // Line Status Interrupt
            inportb(COM1_LINE_STATUS);
            break;
        }
      }
      outportb(PIC_COMMAND, PIC_EOI);
    }
    
    void Output_Interrupt() {
      if (Com1.Status == WRITING) {
        if (*Com1.Out_Count != *Com1.Out_Done) {
          // Write next char to com port
          outportb(COM1_BASE, *Com1.Out_Buffer);
          Com1.Out_Buffer++;
          (*Com1.Out_Done)++;
        } else {
          Com1.Status = IDLE;
          *Com1.Event_Flag = EVENT_COMPLETE;
          outportb(COM1_INTERRUPT, inportb(COM1_INTERRUPT) & ~0x02);
        }
      }
    }
    
    // End COM1 Interrupt Setup Functions
    
    /* com_open
       Version 0.1
       April 2, 2009
    */
    int com_open(int *eflag_p, int baud_rate) {
      int Baud_Rate_Div;
      int Return_Val = COM_OPEN_SUCCESS;
    
      if      (Com1.Is_Open)  Return_Val = COM_OPEN_PORT_OPEN;
      else if (eflag_p == 0)  Return_Val = COM_OPEN_INV_FLAG;
      else if (baud_rate < 0) Return_Val = COM_OPEN_INV_BAUD;
      else {
        // Initialize Com1 DCB
        Com1.Is_Open = TRUE;
        Com1.Event_Flag = eflag_p;
        Com1.Status = IDLE;
        Com1.Ring_Buffer_In = 0;
        Com1.Ring_Buffer_Out = 0;
        Com1.Ring_Buffer_Count = 0;
      
        // Set up New Interrupts
        outportb(COM1_LINE_CONTROL,  0x00);             // Set DLAB = 0
        outportb(COM1_INTERRUPT,     0x00);             // Turn off interrupts
    
        old_COM1_Interrupt = getvect(COM1_INTVECT);     // Save Old Interrupt
        setvect(COM1_INTVECT, COM1_Interrupt);          // Set New Interrupt
    
        Baud_Rate_Div = 115200 / (long) baud_rate;
    
        outportb(COM1_LINE_CONTROL,  0x80);             // Set DLAB = 1
        outportb(COM1_DL_LSB, Baud_Rate_Div & 0xFF);    // Set Baud rate - Divisor Latch Low Byte
        outportb(COM1_DL_MSB, (Baud_Rate_Div >> 8) & 0xFF); // Set Baud rate - Divisor Latch High Byte
        outportb(COM1_LINE_CONTROL,  0x03);             // 8 Bits, No Parity, 1 Stop Bit
        disable();
        outportb(PIC_MASK, (inportb(PIC_MASK) & ~0x80));// Set Programmable Interrupt Controller
        enable();
        outportb(COM1_MODEM_CONTROL, 0x08);             // Enable Serial Interrupts
        outportb(COM1_INTERRUPT,     0x01);             // Enable Input Ready Interrupts
      }
    
      return Return_Val;
    }
    
    
    /* com_close
       Version 0.1
       April 2, 2009
    */
    int com_close() {
      int Return_Val = COM_CLOSE_SUCCESS;
    
      if (!Com1.Is_Open) Return_Val = COM_CLOSE_NOT_OPEN;
      else {
        Com1.Is_Open = FALSE;
        // Reset Communication Protocol to original settings
        outportb(COM1_LINE_CONTROL, 0x00);         // Set DLAB = 0
        outportb(COM1_MODEM_CONTROL, 0x00);        // Disable Serial Interrupts
        outportb(COM1_INTERRUPT, 0x00);            // Turn off interrupts
        disable();
        outportb(PIC_MASK, (inportb(PIC_MASK) & 0x10)); // Set Programmable Interrupt Controller
        enable();
        setvect(COM1_INTVECT, old_COM1_Interrupt); // Restore Old Interrupt Vector
      }
    
      return Return_Val;
    }
    
    
    /* com_write
       Version 0.1
       April 2, 2009
    */
    int com_write(char *buf_p, int *count_p) {
      int Return_Value = COM_WRITE_SUCCESS;
    
      if      (!Com1.Is_Open)       Return_Value = COM_WRITE_NOT_OPEN;
      else if (Com1.Status != IDLE) Return_Value = COM_WRITE_DEV_BUSY;
      else if (buf_p == 0)          Return_Value = COM_WRITE_INV_BUFF;
      else if (count_p == 0)        Return_Value = COM_WRITE_INV_COUNT;
      else {
        Com1.Out_Buffer = buf_p;
        Com1.Out_Count = count_p;
        *Com1.Out_Done = 0;
        Com1.Status = WRITING;
        *Com1.Event_Flag = EVENT_IN_PROGRESS;
        
        // Write first char to com port
        outportb(COM1_BASE, *Com1.Out_Buffer);
        Com1.Out_Buffer++;
        Com1.Out_Done++;
    
    	  outportb(COM1_INTERRUPT, inportb(COM1_INTERRUPT) | 0x02);
      }
      return Return_Value;
    }
    
    // CODE BELOW WAS PROVIDED AND CANNOT BE CHANGED
    
    
    
    
    
    
    void main(void)
    {
    	int e_flag;	/* event flag */
    	int ix;		/* loop index */
    	int rc;		/* function return code */
    	char buffer[BUFLEN]; /* output buffer */
    	int length;
    	long tstart;
    
    	/* open com port */
    	rc = com_open( (int *) &e_flag, 1200);
    	if ( rc != 0) {
    		printf("\nOPEN failed!\n");
     		printf("error code = %d\n",rc);
    		abort_test();
    	}
    
    	/* fill buffer with Xs */
    	for (ix=0; ix<BUFLEN; ix++) buffer[ix] = 'X';
    
     	/* insert test string */
     	strcpy(buffer,"This is a test of com driver output  ");
    	strcat(buffer,"abcdefghijklmnopqrstuvwxyz 0123456789\012\015");
    	length = strlen(buffer);
    
    	/* output test string the specified number of times */
    	for (ix=1; ix<=REPEAT_COUNT; ix++) {
    		e_flag = 0;
    		rc = com_write((char *) buffer, (int *) &length);
    		if (rc != 0) {
    			printf("\nWRITE error!\n");
    			printf("error code = %d\n",rc);
    			abort_test();
    		}
    
    		/* loop until output is done */
    		tstart = time(NULL);
    		while (e_flag == 0) {
    			if ((time(NULL) - tstart) > TIME_LIMIT) {
    				printf("\nTIMEOUT: event flag not set\n");
    				abort_test();
    			}
    		}
            }
    
    
    	/* output final message */
    	e_flag = 0;
    	length = 31;
    	rc = com_write((char *) "End of Com Driver Output Test\012\015",
    				(int *) &length);
    	if (rc != 0) {
    		printf("\nWRITE error on final message!\n");
    		printf("error code = %d\n",rc);
    		abort_test();
    	}
    
    	/* loop until output is done */
    	tstart = time(NULL);
    	while (e_flag == 0) {
    		if ((time(NULL) - tstart) > TIME_LIMIT) {
    			printf("\nTIMEOUT: event flag not set\n");
    			abort_test();
    		}
    	}
    
    	/* close the com port */
    	rc = com_close();
    	if ( rc != 0) {
    		printf("\nCLOSE failed!\n");
     		printf("error code = %d\n",rc);
    		exit();
    	}
    
    	printf("Test completed successfully!\n");
    
    }
    
    
    /*
    	Abort after error
    */
    void abort_test()
    {
    	int err;
    
    	printf("\nAborting com port test\n");
    	err = com_close();
    	if (err!=OK) printf("Error on close\n");
    
    	exit();
    
    }
    When I run this, the first character of buffer ('T') is received, but no other chars are. I eventually get the following output...

    TIMEOUT : event flag not set
    Aborting com port test

    I'm not sure what is wrong...

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Get rid of this:
    Code:
    		/* fill buffer with Xs */
    	for (ix=0; ix<BUFLEN; ix++) buffer[ix] = 'X';
    Change this:
    Code:
    char buffer[BUFLEN] = {0};
    Zero filling your buffer seems smarter than filling it with Xs, especially since you fill the entire thing, including the last space, and then use it like a string later on.

    Also, no where in your code that I can find, is there anything that EVER sets your flag to anything other than zero. It's always zero. So it's always going to say it's timing out. Furthermore, if you have defined event states, and you're checking event states, why do you keep switching between using those flags and not using them?
    Code:
    if( e_flag == 0 )
    You should be keeping consistent and always using:
    Code:
    if( e_flag == EVENT_INPROGRESS )
    Or whatever your event is called. Half the time you just use a number, the other half you use your macro.

    That combine with you using globals compared to locals, makes reading your code much more difficult.

    Quzah.
    Hope is the first step on the road to disappointment.

  12. #12
    Registered User
    Join Date
    Feb 2009
    Posts
    278
    I agree with your comments, however, the code you're talking about (main()) was provided by my instructor (in my project it is in a separate file) and cannot be changed. Only com_open, com_close, com_write and the interrupt functions were written by me and need to be fixed.

    From what I can tell after doing some testing, the interrupts are not working. Any ideas?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. pointer problem or so...
    By TL62 in forum C Programming
    Replies: 19
    Last Post: 01-12-2008, 11:45 PM
  2. Global Variables
    By Taka in forum C Programming
    Replies: 34
    Last Post: 11-02-2007, 04:25 AM
  3. "dereferencing pointer to incomplete type"
    By incognito54 in forum C Programming
    Replies: 2
    Last Post: 11-01-2005, 09:50 AM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 04:00 PM
  5. Passing pointers between functions
    By heygirls_uk in forum C Programming
    Replies: 5
    Last Post: 01-09-2004, 06:58 PM

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