我需要一些帮助来理解为什么我在运行代码后出现分段错误,或者当内存使用超出内存时它为什么不停止。我一直试图做各种事情,看看cp和ip在哪里,大部分时间他们都是一样的。我已经根据教授给我们的内容建立了这段代码。我写的代码的不同版本会给我" p6应该是NULL,但是地址"。 我真的想要理解这一点,我并不是在寻找任何人为我发布代码。 任何帮助或建议表示赞赏。我在这里搜索了谷歌,youtube,但还没找到任何帮助。是的,我意识到这很糟糕所以请不要粗鲁我只是想学习。感谢。
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,®ion);
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 }
答案 0 :(得分:1)
你p6
的第一次尝试失败了,但是作为副作用,在第35行保释之前,你仍然会在第32行更新全局memused
。
因此,p6
的下一次尝试也会在第35行失败。(所有行号相对于顶部源列表。)
如果您查看p6
的第二次尝试检查(底部列表中的第64行)p6
再次为NULL
; NULL % 16 == 0
,因此我们不输入if
声明。这意味着我们会转到memset
,其目标是NULL
指针。 (因此SIGSEGV
。)
您在顶部列表第33行所做的检查应该可以在第31行之后完成,并且应该在不影响全局状态的情况下完成。即,if (mem < (memused + num_bytes_to_allocate))
。然后memused
只有在您决定不提前纾困时才会更新。