LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 974|回复: 6

发现一个定义变量次序出现的问题

[复制链接]
发表于 2003-6-27 21:32:15 | 显示全部楼层 |阅读模式
  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <sys/types.h>
  4. #include <sys/sem.h>
  5. #include <sys/ipc.h>
  6. #define NUM 5
  7. #define TIMES 2
  8. union semun {
  9. int val;
  10. struct semid_ds *buf;
  11. ushort *array;
  12. };
  13. P(int sem,int x,int y)
  14. {
  15. int num1,num2,i=TIMES;
  16. struct sembuf lacquire={sem,-1,SEM_UNDO};
  17. struct sembuf racquire={sem,-1,SEM_UNDO};
  18. struct sembuf lrelease={sem,1,SEM_UNDO};
  19. struct sembuf rrelease={sem,1,SEM_UNDO};
  20. lacquire.sem_num=(x+4)%5;
  21. racquire.sem_num=y%5;
  22. lrelease.sem_num=(x+4)%5;
  23. rrelease.sem_num=y%5;
  24. for(i=0;i<NUM;i++)
  25. {
  26.         if((num1=semctl(sem,x,GETVAL),0)==-1)
  27.         {perror("semctl");exit(3);}
  28.         if((num2=semctl(sem,y,GETVAL),0)==-1)
  29.         {perror("semctl");exit(3);}
  30.         if(num1&&num2)
  31.         {
  32.         printf("The No.%d philosopher is eating!\n",x);
  33.         if(semop(sem,&racquire,1)==-1)
  34.                 {perror("semop");exit(5);}
  35.         if(semop(sem,&lacquire,1)==-1)
  36.                 {perror("semop");exit(5);}
  37.         sleep(1);
  38.         if(semop(sem,&lrelease,1)==-1)
  39.                 {perror("semop");exit(6);}
  40.         if(semop(sem,&rrelease,1)==-1)
  41.                 {perror("semop");exit(6);}
  42.         }
  43.         else
  44.         {
  45.         printf("The No.%d philosopher is thinking!\n",x);
  46.         continue;
  47.         }
  48. }
  49. }
  50. main()
  51. {
  52. key_t ipc_key;
  53. struct  semid_ds sem_buf;
  54. int sem,i;
  55. union semun arg;
  56. int *p,*pid,cpid;[color=red]
  57. //这里要是改成int *p,*pid,cpid;union semun arg;就则出现:段错误
  58. //以前看过一个堆栈生长的贴子,但还不明白当变量是指针时,要压入什么到栈里
  59. [/color]ushort sem_array[5]={1,1,1,1,1};
  60. *pid=getpid();//get the pid of the parent prodecure
  61. p=pid;
  62. arg.array=sem_array;
  63. ipc_key=ftok(".",'c');
  64. if((sem=semget(ipc_key,NUM,IPC_CREAT))==-1)
  65. {perror("semget");exit(1);}
  66. if(semctl(sem,NUM,SETALL,arg)==-1)
  67. {perror("semctl SETALL");exit(2);}
  68. /*for(i=0;i<NUM;i++)
  69.         {
  70.         if((cpid=semctl(sem,i,GETVAL,0))==-1)
  71.         {perror("semctl GETVAL");exit(8);}
  72.         printf("%5d",cpid);
  73.         } */
  74. for(i=1;i<NUM+1;i++)
  75.         {
  76.         if((cpid=fork())==-1)
  77.                 {
  78.                 perror("fork error!");
  79.                 exit(1);
  80.                 }
  81.         else
  82.         if(cpid==0)
  83.         {
  84.         *(pid+i)=getpid();
  85.         break;
  86.         }
  87.         else
  88.         continue;
  89.         }
  90. for(i=1;i<NUM+1;i++)
  91.         {
  92.         cpid=getpid();
  93.         if(cpid==*(p+i))
  94.         {
  95.         P(sem,i,i+1);
  96.         }
  97.         else
  98.         continue;
  99.         }
  100. }
复制代码
发表于 2003-6-28 14:14:26 | 显示全部楼层
没有细看

可能你的指针访问非法了吧

使用调试器跟一下
 楼主| 发表于 2003-6-28 17:56:10 | 显示全部楼层
因为编译时就出现错误。没有生成.o文件。所以无法调试。
发表于 2003-6-28 21:36:15 | 显示全部楼层
我在dev-c++下与
main()
{
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
int *p,*pid,cpid;
union semun arg;
}

这样没错

我想你会不会是其它地方的错误
发表于 2003-6-29 00:59:24 | 显示全部楼层
调换前用gcc可以顺利编译和运行
调换后用gcc加-g后直接编译成a.out通过,但运行出现segment failt错误
-g gdb调试显示错误大概在ipc_key=ftok(".",'c');

不懂。关注
发表于 2003-6-30 17:27:40 | 显示全部楼层
和顺序无关
搞了半天,
你程序的指针p和pid没有分配空间就用p+1,pid+1的,内存乱了,就segment failt
我已修改:错误处加长线标出
  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <sys/types.h>
  4. #include <sys/sem.h>
  5. #include <sys/ipc.h>
  6. #define NUM 5
  7. #define TIMES 2
  8. union semun {
  9.         int val;
  10.         struct semid_ds *buf;
  11.         ushort *array;
  12. };
  13. void P(int sem,int x,int y)
  14. {
  15.         int num1,num2,i=TIMES;
  16.         struct sembuf lacquire={sem,-1,SEM_UNDO};
  17.         struct sembuf racquire={sem,-1,SEM_UNDO};
  18.         struct sembuf lrelease={sem,1,SEM_UNDO};
  19.         struct sembuf rrelease={sem,1,SEM_UNDO};
  20.         lacquire.sem_num=(x+4)%5;
  21.         racquire.sem_num=y%5;
  22.         lrelease.sem_num=(x+4)%5;
  23.         rrelease.sem_num=y%5;
  24.         for(i=0;i<NUM;i++)
  25.         {
  26.                        if((num1=semctl(sem,x,GETVAL),0)==-1)
  27.                                {perror("semctl");exit(3);}
  28.                        if((num2=semctl(sem,y,GETVAL),0)==-1)
  29.                                {perror("semctl");exit(3);}
  30.                        if(num1&&num2){
  31.                                printf("The No.%d philosopher is eating!\n",x);
  32.                                if(semop(sem,&racquire,1)==-1)
  33.                                        {perror("semop");exit(5);}
  34.                                if(semop(sem,&lacquire,1)==-1)
  35.                                        {perror("semop");exit(5);}
  36.                                sleep(1);
  37.                                if(semop(sem,&lrelease,1)==-1)
  38.                                        {perror("semop");exit(6);}
  39.                                if(semop(sem,&rrelease,1)==-1)
  40.                                        {perror("semop");exit(6);}
  41.                        }
  42.                        else{
  43.                        printf("The No.%d philosopher is thinking!\n",x);
  44.                        continue;
  45.                    }
  46.         }
  47. }
  48. //
  49. int main()
  50. {
  51.         key_t ipc_key;
  52. //        struct  semid_ds sem_buf;___________________用-Wall参数编译可看出这个变量程序从没用过
  53.         int sem,i;
  54.         ushort sem_array[5]={1,1,1,1,1};
  55.        
  56.        
  57.        
  58.        
  59.         //union semun arg;
  60.         int *p,*pid,cpid;
  61.         union semun arg;
  62. //分配空间………………………………………………………………
  63.         pid=(int *)(malloc(5*sizeof(int)));
  64.         p=(int *)(malloc(5*sizeof(int)));
  65.        
  66.        
  67.        
  68. //这里要是改成int *p,*pid,cpid;union semun arg;就则出现:段错误
  69. //以前看过一个堆栈生长的贴子,但还不明白当变量是指针时,要压入什么到栈里
  70.        
  71.         *pid=getpid();//get the pid of the parent prodecure
  72.         p=pid;
  73.         arg.array=sem_array;
  74.         ipc_key=ftok(".",'c');
  75.         if((sem=semget(ipc_key,NUM,IPC_CREAT))==-1)
  76.                 {perror("semget");exit(1);}
  77.         if(semctl(sem,NUM,SETALL,arg)==-1)
  78.                 {perror("semctl SETALL");exit(2);}
  79. //        /*for(i=0;i<NUM;i++)
  80. //                {
  81. //      if((cpid=semctl(sem,i,GETVAL,0))==-1)
  82. //        {perror("semctl GETVAL");exit(8);}
  83. //        printf("%5d",cpid);
  84. //        } */
  85.         for(i=1;i<NUM+1;i++){
  86.                 if((cpid=fork())==-1){
  87.                         perror("fork error!");
  88.                         exit(1);
  89.                 }
  90. //---------------------------------------------------pid+1//以前是指针pid+1没有分配空间
  91.                 else if(cpid==0){
  92.                         *(pid+i)=getpid();
  93.                         break;
  94.                 }
  95.                 else
  96.                 continue;
  97.         }
  98.        
  99.         for(i=1;i<NUM+1;i++){
  100.                 cpid=getpid();
  101.   //……………………………………………………………………错误同上p
  102.                 if(cpid==*(p+i)){
  103.                         P(sem,i,i+1);
  104.                 }
  105.                 else
  106.                 continue;
  107.         }
  108.         exit(0);
  109. }
复制代码
指针要小心用
附带问这里p和pid要free吗?
发表于 2003-6-30 18:05:36 | 显示全部楼层
当然,动态分配的内存都要自己free。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表