我需要一些帮助来理解为什么在运行代码后为什么会出现分段错误,或者当使用的内存超过内存时为什么它不会停止。我一直在尝试做各种事情来查看cp和ip的位置,并且在大多数情况下它们是相同的。我已经根据我们的教授给我们的代码构建了这段代码。我编写的代码的不同版本将给我“ p6应该为NULL,但为地址”。
我只是想真正地理解这一点,我不是在寻找想要为我发布代码的人。
任何帮助或建议,表示赞赏。我已经在此处youtube上搜索过Google,但是还没有找到任何帮助。是的,我知道这很糟糕,所以请不要粗鲁,我只是想学习。谢谢。

      1
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <errno.h>
      5 #include <sys/mman.h>
      6 #include <sys/types.h>
      7 #include <unistd.h>
      8
      9     int mem,memused,i, pgsz, *ip;
     10     unsigned char *cp;
     11     void *region;
     12
     13 void heap_init(int num_pages_for_heap)
     14 {
     15     pgsz = getpagesize();
     16     pgsz*=num_pages_for_heap;
     17      mem=pgsz;
     18     region = mmap(NULL, pgsz, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
     19     if (region == ((void *) -1))
     20     {
     21         perror("mmap");
     22        // return 1;
     23     }
     24
     25 }
     26
     27 void *heap_alloc(int num_bytes_to_allocate)
     28 {
     29  if(num_bytes_to_allocate%16 != 0)
     30   {  num_bytes_to_allocate+=8;}
     31
     32     memused+=num_bytes_to_allocate;
     33 if(mem<memused)
     34 { cp=NULL;
     35   return cp;
     36 }
     37
     38 else{
     39  printf("mem used: %d mem: %d region: %p  %d\n",memused,mem,region,&region);
     40    cp = (unsigned char *)region;
     41    *(cp+num_bytes_to_allocate)='a';
     42
     43     ip = (int *)region;
     44    //printf("ip %p, %d\n",ip, &ip);
     45
     46   // *(ip+num_bytes_to_allocate);  // region+1004
     47   // printf("ip %p, %d\n",ip, &ip);
     48   //  *ip+=(num_bytes_to_allocate);
     49
     50     //printf("ip %p\n",ip);
     51     // cp = (unsigned char *)region;
     52     //*cp+=(num_bytes_to_allocate);
     53     //printf("cp %p, %d\n",cp,&cp);
     54
     55  for (i=999; i < num_bytes_to_allocate; i++)//I dont understand why the prof used 999.
     56     {
     57       *(cp+i);
     58
     59     }
     60     printf("\n");
     61
     62
     63 return cp;
     64 }
     65 }
     66 void heap_free(void *pointer_to_area_to_free)
     67 {
     68  //   return;
     69 }


//输出当前使用的代码:

  mem used: 2000 mem: 8192 region: 0x7f8a62941000  6296176

  mem used: 4000 mem: 8192 region: 0x7f8a62941000  6296176

  mem used: 6000 mem: 8192 region: 0x7f8a62941000  6296176

  mem used: 7008 mem: 8192 region: 0x7f8a62941000  6296176

  mem used: 8016 mem: 8192 region: 0x7f8a62941000  6296176

  Segmentation fault


//这是他给我们的驱动程序:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4
  5 void heap_init(int num_pages_for_heap);
  6 void *heap_alloc(int num_bytes_to_allocate);
  7 void heap_free(void *pointer_to_area_to_free);  // not used in this test
  8
  9 int main(int argc, char *argv[])
 10 {
 11     char *p1, *p2, *p3, *p4, *p5, *p6;
 12
 13     heap_init(2);
 14
 15     p1 = (char *) heap_alloc(2000);
 16     if ((long int)p1 % 16 != 0)
 17     {
 18         printf("p1 bad %p  pmod16 %d\n",p1,((long int)p1)%16);
 19         exit(-1);
 20     }
 21     memset(p1,'X',2000);
 22
 23     p2 = (char *) heap_alloc(2000);
 24     if ((long int)p2 % 16 != 0)
 25     {
 26         printf("p2 bad %p  pmod16 %d\n",p2,((long int)p2)%16);
 27         exit(-1);
 28     }
 29     memset(p2,'X',2000);
 30
 31     p3 = (char *) heap_alloc(2000);
 32     if ((long int)p3 % 16 != 0)
 33     {
 34         printf("p3 bad %p  pmod16 %d\n",p3,((long int)p3)%16);
 35         exit(-1);
 36     }
 37     memset(p3,'X',2000);
 38
 39     p4 = (char *) heap_alloc(1000);
 40     if ((long int)p4 % 16 != 0)
 41     {
 42         printf("p4 bad %p  pmod16 %d\n",p4,((long int)p4)%16);
 43         exit(-1);
 44     }
 45     memset(p4,'X',1000);
 46
 47     p5 = (char *) heap_alloc(1000);
 48     if ((long int)p5 % 16 != 0)
 49     {
 50         printf("p5 bad %p  pmod16 %d\n",p5,((long int)p5)%16);
 51         exit(-1);
 52     }
 53     memset(p5,'X',1000);
 54
 55
 56     p6 = (char *) heap_alloc(1500);  // try 1500 first
 57     if (p6 != NULL)
 58     {
 59         printf("p6 should have been NULL, but is %p\n",p6);
 60         exit(-1);
 61     }
 62
 63     p6 = (char *) heap_alloc(50);   // then just get 50
 64     if ((long int)p6 % 16 != 0)
 65     {
 66         printf("p6 bad %p  pmod16 %d\n",p6,((long int)p6)%16);
 67         exit(-1);
 68     }
 69     memset(p6,'X',50);
 70
 71     printf("DONE\n");
 72
 73     return 0;
 74 }

最佳答案

第一次尝试失败了,但是效果是,副作用是,在第35行保释之前,您仍然在第32行更新了全局p6

因此,在memused处的下一次尝试也停留在第35行。(所有行号均相对于顶部源列表)。

如果您查看在p6处第二次尝试的检查(底部清单的第64行),则p6再次为p6NULL,因此我们不输入NULL % 16 == 0语句。这意味着我们进入if,其目的地是memset指针。 (因此NULL。)

您在顶部列表中第33行进行的检查可能应该在第31行之后进行,并且应该在不影响全局状态的情况下进行。即SIGSEGV。然后,只有在您决定不提早纾困时,才应更新if (mem < (memused + num_bytes_to_allocate))

10-08 04:15