简体   繁体   中英

Simple question about pointer in c programming

I was writing a simple shared memory test program like below. And I used a line like below.

e_intf[i % 8].flag = i;

I thought it should be like below.

e_intf[i % 8]->flag = i;

But if I use "->" operator, I have errors. This is a full source code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>

#define SHM_KEY 0x9998

typedef struct _ethernet_interface {
   char name[8];
   int32_t flag;
} Ethernet_Interface_t;

int32_t memory_update(void)
{
   int32_t i = 0;
   int32_t shmid;
   Ethernet_Interface_t *e_intf;
   int32_t ret;

   shmid = shmget(SHM_KEY, 8 * sizeof(Ethernet_Interface_t), 0644|IPC_CREAT);
   if (shmid == -1)
   {
      perror("Shared Memory");
      return -1;
   }

   e_intf = shmat(shmid, NULL, 0);
   if (e_intf == (void *)-1)
   {
      perror("Shared Memory Attach");
      return -1;
   }

   while (1)
   {
      e_intf[i % 8].flag = i;
      if (i < 8)
      {
         sprintf(e_intf[i % 8].name, "%s%d", "eth", (i % 8));
      }
      printf("memory_update : e_intf[%d].name = %s, e_intf[%d] = %d\n", i % 8, e_intf[i % 8].name, (i % 8), i);
      sleep(2);
      i++;
   }

   ret = shmdt(e_intf);
   if (ret == -1)
   {
      perror("shmdt");
      return -1;
   }

   return 0;
}

int32_t memory_read(void)
{
   int32_t i;
   int32_t shmid;
   Ethernet_Interface_t *e_intf;
   int32_t ret;

   shmid = shmget(SHM_KEY, 8 * sizeof(Ethernet_Interface_t), 0644|IPC_CREAT);
   if (shmid == -1)
   {
      perror("Shared Memory");
      return -1;
   }

   e_intf = shmat(shmid, NULL, 0);
   if (e_intf == (void *)-1)
   {
      perror("Shared Memory Attach");
      return -1;
   }

   i = 0;
   while (1)
   {
      printf("[%d]memory_read : index = %d\n", i, (i % 8));
      printf("[%d]memory_read : e_intf[%d].name = %s\n", i, (i % 8), e_intf[i % 8].name);
      printf("[%d]memory_read : e_intf[%d].flag = %d\n", i, (i % 8), e_intf[i % 8].flag);
      if (e_intf[i % 8].flag == 42)
      {
         printf("[%d]memory_read : Exiting\n", i);
         break;
      }
      sleep(1);
      i++;
   }

   ret = shmdt(e_intf);
   if (ret == -1)
   {
      perror("shmdt");
      return -1;
   }

   ret = shmctl(shmid, IPC_RMID, 0);
   if (ret == -1)
   {
      perror("shmctl");
      return -1;
   }

   return 0;
}

int32_t main(int32_t argc, char *argv[])
{
   pid_t pid;

   pid = fork();
   if (pid == 0)
   {
      /* child process */
      memory_update();
   }
   else
   {
      /* parent process */
      memory_read();
   }

   exit(0);
}

But when I made another simple test program for pointer operation. I can use "->" operator as I expected. Here is the source code for the test program for pointer operation.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

typedef struct _ethernet_interface {
   char name[8];
   int32_t flag;
} Ethernet_Interface_t;

int32_t main(int32_t argc, char *argv[])
{
   Ethernet_Interface_t intf;
   Ethernet_Interface_t *p_intf;

   p_intf = malloc(sizeof(Ethernet_Interface_t));
   intf.flag = 1111;
   p_intf->flag = 2222;

   printf("intf.flag = %d\n", intf.flag);
   printf("p_intf->flag = %d\n", p_intf->flag);

   return 0;
}

Can someone point out why I am confused with these 2 cases?

The answer is very simple - index dereferences the pointer:

pointer[n]  === *(pointer + n)

so in your case:

e_intf[i % 8]  === *(e_intf + i % 8)

and

e_intf[i % 8].flag  == (*(e_intf + i % 8)).flag

if you want to use the -> operator you need pointer, not referenced object.

(&e_intf[i % 8]) -> flag

or

(e_intf + i % 8) -> flag

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM