【问题标题】:c language memory management with string segments and fifos带字符串段和fifos的c语言内存管理
【发布时间】:2017-01-31 21:49:04
【问题描述】:

晚上好,我需要创建一个程序,它会要求 3 个段名称,每个段都会要求一个值。我的总内存是 2000 个单位。我需要使用 structs 和 fifos 在客户端(将从用户那里获取输入)和服务器(将处理总单元)之间进行通信。客户端将发回每个段的开始和结束地址,以及任何剩余的内存。

我运行后的问题是我遇到了分段错误。我真的看不出我可能在哪里覆盖了内存,或者我是否在某个时候重置了内存。欢迎任何意见或建议,谢谢。

客户端代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>


// creating the struct for the program
struct probsiz{
   int seg1 [1]; //segment 1 size
   int seg2 [1]; //segment 2 size
   int seg3 [1]; //segment 3 size
   int segsum [7]; //sum for all the segments
   int leftov [1]; //memory leftovers

} ;

struct probseg {     

   char segment[64]; //segments
};


main (void)
{
  struct probsiz numbs; //defining the structures
  struct probseg names; 

  int fda;  // to write to character server
  int fdb;  // to read response from character server

  //setting up the memory

  memset(numbs.seg1, 0, sizeof(struct probsiz)); //setting up memory for the first segment
  memset(numbs.seg2, 0, sizeof(struct probsiz)); //setting up memory for the second segment
  memset(numbs.seg3, 0, sizeof(struct probsiz)); //setting up memory for the third segment
  memset(numbs.segsum, 0, sizeof(struct probsiz));// setting up memory for the sum of all segments
  memset(numbs.leftov, 0, sizeof(struct probsiz)); //setting up memory for the first segment
  memset(names.segment, 0, sizeof (struct probseg));// setting up memory for the segments




  //reading the requested memory and segment name from the user
  printf("Client: Please enter requested memory 1: ");
  scanf("%d", &numbs.seg1[0]);
  while (numbs.seg1 <=0){
      printf("Client: please enter a valid request: ");
      scanf("%d", &numbs.seg1[0]);
  }
  printf("Client: Please enter segment 1 name: ");
  scanf("%s", names.segment[0]);


  printf("Client: Please enter requested memory 2: ");
  scanf("%d", &numbs.seg2[0]);
  while (numbs.seg1 <=0){
      printf("Client: please enter a valid request: ");
      scanf("%d", &numbs.seg2[0]);
  }
  printf("Client: Please enter segment 2 name: ");
  scanf("%s", names.segment[1]);


  printf("Client: Please enter requested memory 3: ");
  scanf("%d", &numbs.seg3[0]);
  while (numbs.seg3 <=0){
      printf("Client: please enter a valid request: ");
      scanf("%d", &numbs.seg3[0]);
  }
  printf("Client: Please enter segment 3 name: ");
  scanf("%s", names.segment[2]);

  //send and write into the fifos

  printf("\nClient: Got the sizes sent now waiting for server's response\n");

 write(fda, &numbs, sizeof(struct probsiz));
 write(fda, &names, sizeof(struct probseg));


  //read from the fifos
 read(fdb, &numbs, sizeof(struct probsiz));

 if (numbs.leftov[0] >=0) {

     printf("\nClient: address for segment 1 is: %d - %d", numbs.segsum[0], numbs.segsum[1]);
     printf("\nClient: address for segment 2 is: %d - %d", numbs.segsum[2], numbs.segsum[3]);
     printf("\nClient: address for segment 3 is: %d - %d", numbs.segsum[4], numbs.segsum[5]);
     printf("\nClient: leftover memory is: %d", numbs.leftov[0]);
     printf("\nall done!");
 }
 else
 {
     printf("\nClient: segment size is over the capacity, please try again");
     printf("\nall done!\n");

 }

  //this closes the fifos
  close(fda);
  close(fdb);


  printf ("\nall done!\n");

}

服务器代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>



// creating the struct for the program
struct probsiz{
   int seg1 [1]; //segment 1 size
   int seg2 [1]; //segment 2 size
   int seg3 [1]; //segment 3 size
   int segsum [1]; //sum for all the segments
   int leftov [1]; //memory leftovers

} ;

struct probseg {     

   char segment[64]; //for the segments
};

main (void)
{
  struct probsiz numbs; //  structure definitions
  struct probseg names;


  int fda;  // to read from client char
  int fdb;  // to write to client char
  int finish;   // lets me know that client is done
  int i;    // because C needs this defined as int
  int m=2000; //total memory units
  int mtot;  //memory total from the sum of all the segments

  //setting up the memory 

  memset(numbs.seg1, 0, sizeof(struct probsiz)); //setting up memory for the first segment
  memset(numbs.seg2, 0, sizeof(struct probsiz)); //setting up memory for the second segment
  memset(numbs.seg3, 0, sizeof(struct probsiz)); //setting up memory for the third segment
  memset(numbs.segsum, 0, sizeof(struct probsiz));// setting up memory for the sum of all segments
  memset(numbs.leftov, 0, sizeof(struct probsiz)); //setting up memory for the first segment
  memset(names.segment, 0, sizeof (struct probseg));// setting up memory for the segments


  /* Create the fifos and open them  */
  if ((mkfifo("FIFO1",0666)<0 && errno != EEXIST))
    {
    perror("cant create FIFO1");
    exit(-1);
    }
  if ((mkfifo("FIFO2",0666)<0 && errno != EEXIST))
    {
    perror("cant create FIFO2");
    exit(-1);
    }
  if((fda=open("FIFO1", O_RDONLY))<0)
     printf("cant open fifo to write");
  if((fdb=open("FIFO2", O_WRONLY))<0)
     printf("cant open fifo to read");

  read(fda, &numbs, sizeof(struct probsiz)); //read the sizes
  read(fda, &names, sizeof(struct probseg)); //read the segments

  //printing out the characters on the server side to validate the data in

  strcpy(names.segment, names.segment);
  mtot=numbs.seg1[0]+numbs.seg2[0]+numbs.seg3[0];
  numbs.leftov[0]=m-mtot;

  printf("Server: just got segment 1: %s", names.segment[0]);
  printf("Server: just got segment 1 size: %d", numbs.seg1[0]);

  printf("Server: just got segment 2: %s", names.segment[0]);
  printf("Server: just got segment 2 size: %d", numbs.seg2[0]);

  printf("Server: just got segment 3: %s", names.segment[0]);
  printf("Server: just got segment 3 size: %d", numbs.seg3[0]);


  //calculation of memory addresses
  numbs.segsum[0]=0;
  numbs.segsum[1]= numbs.seg1[0]-1;
  numbs.segsum[2]= numbs.seg1[0];
  numbs.segsum[3]= numbs.segsum[2]+numbs.seg2[0]-1;
  numbs.segsum[4]= numbs.segsum[3]+1;
  numbs.segsum[5]= numbs.segsum[4]+numbs.seg3[0];
  numbs.segsum[6]=0;


  write(fdb, &numbs, sizeof(struct probsiz));

  if (numbs.leftov[0] >=0) {

     printf("\nClient: address for segment 1 is: %d - %d", numbs.segsum[0], numbs.segsum[1]);
     printf("\nClient: address for segment 2 is: %d - %d", numbs.segsum[2], numbs.segsum[3]);
     printf("\nClient: address for segment 3 is: %d - %d", numbs.segsum[4], numbs.segsum[5]);
     printf("\nClient: leftover memory is: %d", numbs.leftov[0]);
     printf("\nall done!");
 }
 else
 {
     printf("\nClient: segment size is over the capacity, please try again");
     printf("\nall done!\n");

 }

  if(finish == 1)
    printf("\nServer: This says I am ready to close ");
  close(fda);
  close(fdb);
  unlink("FIFO1");
  unlink("FIFO2");
}

【问题讨论】:

  • 这里是清晨... ;)
  • 用符号编译(对于 GCC 使用选项 -g),然后使用调试器运行程序(例如 GBD (gdb))。在它崩溃后执行bt &lt;enter&gt; 并找到导致程序崩溃的代码行及其调用堆栈。
  • 哪个程序崩溃,客户端或服务器或两者兼而有之?
  • 客户端崩溃,服务器没有得到任何数据:(
  • 终于让客户端工作了,但是服务器没有收到任何数据,可能是我的fifos工作不正常吗?

标签: c memory-management struct fifo segments


【解决方案1】:

不确定这是唯一的问题,但您的 memset 可能导致分段错误。

你已经定义了:

struct probsiz{
   int seg1 [1]; //segment 1 size               size = sizeof(int)
   int seg2 [1]; //segment 2 size               size = sizeof(int)
   int seg3 [1]; //segment 3 size               size = sizeof(int)
   int segsum [7]; //sum for all the segments   size = sizeof(int*7)
   int leftov [1]; //memory leftovers           size = sizeof(int)

} ;

probsiz 的总大小为 sizeof(int * 11)

现在让我们看看这一行的例子:

memset(numbs.leftov, 0, sizeof(struct probsiz)); //setting up memory for the first segment

您是在告诉计算机将从 numbs.leftov 开始的 0 填充到整个结构的长度。

希望我能帮上忙

【讨论】:

  • 我今天早上会努力工作,昨晚我真的很累,谢谢你的建议我现在就去工作
  • 好吧,我将 memset 从 sizeof 语句更改为结构上的实际数量,但我仍然遇到分段错误,这可能是因为我将分段名称写在上一个?
  • 终于让客户端工作了,但是服务器没有收到任何数据,可能是我的fifos没有正常工作
  • 1.您将名称读取到 names.segment[0]、names.segment[1] 和 names.segment[2],如果您只计划名称为 1 个字符长,这很好。否则你应该分配 names.seg1[SIZE]、names.seg2[SIZE] 和 names.seg3[SIZE] 2. 你不检查返回值!如果你这样做了,你会注意到你从未打开过 fba 和 fdb...
  • 好的,我会为我的下一个项目修复它,因为我需要再次为客户使用相同的程序。感谢您的建议:)
猜你喜欢
  • 1970-01-01
  • 2010-10-11
  • 2011-10-22
  • 2021-07-28
  • 2013-06-17
  • 1970-01-01
  • 2015-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多