munmap()从函数调用时不起作用

问题描述 投票:0回答:1

我正在编写可与共享内存一起使用的函数库。我正在编写的用于关闭共享内存的函数在到达munmap()部分时会给我一个段错误,但是如果我不使用该函数,而仅在代码末尾放上munmap()和shm_unlink,它将起作用。我对为什么感到非常困惑。代码在下面。

void close_table(table_t *tbl, char* name){
  size_t size = sizeof(tbl->table_size);
  printf("table_size: %d\n", tbl->table_size);
  /* when the first part of if else statement runs its fine */
  if(tbl->numP > 1){
    printf("first if statement\n");
    tbl->numP -= 1;
    munmap(tbl, tbl->table_size);
  }
  /* when second part runs gives seg fault */
  else{
    tbl->numP -= 1;
    munmap(tbl, tbl->table_size);
    //close(tbl->shm_fd);
    shm_unlink(tbl->name);
  }
  // Code omission
}

这是打开表的功能

table_t *open_table(char *name, int record_size, int max_records){

  int shm_fd;
  int table_size;
  void* ptr;
  table_t* tbl;
  table_t controlBlock;
  db_info info;
  data_block data;

  table_size = max_records * sizeof(controlBlock) * sizeof(info) *
    sizeof(data);



  if((shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666)) == -1){
    exit(EXIT_FAILURE);
  }

  ftruncate(shm_fd, table_size);
  ptr = mmap(NULL, table_size, PROT_WRITE | PROT_READ, MAP_SHARED, shm_fd, 
  0);
  tbl = ptr;
  tbl->shm_fd = shm_fd;
  tbl->table_size = table_size;
  tbl->max_records = max_records;
  tbl->record_size = record_size;
  if(tbl->numP >= 1){
    tbl->numP += 1;
  }
  else{
    tbl->numP = 1;
  }

  return tbl;
}

这些是我的结构

typedef struct{
  int dbInfoId;
  int deleted;
}db_info;

typedef struct{
  int shm_fd;
  int numP;
  int control_id;
  char *name;
  int table_size;
  int record_size;
  int max_records;
  db_info* dbInfo;
  void* db;
}table_t;


typedef struct{
  int id;
  void* record;
}data_block;

valgrind表示其为“大小为8的无效读数”>

enter a command (just the number):
1. Add
2. Delete
3. Process
4. Close
5. # of processes
6. exit
4
table_size: 29360128
==6679== Invalid read of size 8
==6679==    at 0x108C42: close_table (in /home/abiodun/Documents/Comp 3713/Assignment3_makeup/main)
==6679==    by 0x108F15: main (main.c:40)
==6679==  Address 0x5654010 is not stack'd, malloc'd or (recently) free'd
==6679== 
==6679== 
==6679== Process terminating with default action of signal 11 (SIGSEGV)
==6679==  Access not within mapped region at address 0x5654010
==6679==    at 0x108C42: close_table (in /home/abiodun/Documents/Comp 3713/Assignment3_makeup/main)
==6679==    by 0x108F15: main (main.c:40)
==6679==  If you believe this happened as a result of a stack
==6679==  overflow in your program's main thread (unlikely but
==6679==  possible), you can try to increase the size of the
==6679==  main thread stack using the --main-stacksize= flag.
==6679==  The main thread stack size used in this run was 8388608.
--6679-- REDIR: 0x50db950 (libc.so.6:free) redirected to 0x4c30cd0 (free)
==6679== 
==6679== HEAP SUMMARY:
==6679==     in use at exit: 0 bytes in 0 blocks
==6679==   total heap usage: 2 allocs, 2 frees, 2,048 bytes allocated
==6679== 
==6679== All heap blocks were freed -- no leaks are possible
==6679== 
==6679== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==6679== 
==6679== 1 errors in context 1 of 1:
==6679== Invalid read of size 8
==6679==    at 0x108C42: close_table (in /home/abiodun/Documents/Comp 3713/Assignment3_makeup/main)
==6679==    by 0x108F15: main (main.c:40)
==6679==  Address 0x5654010 is not stack'd, malloc'd or (recently) free'd
==6679== 
==6679== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

我正在编写可与共享内存一起使用的函数库。每当我到达munmap()部分时,我正在编写的用于关闭共享内存的函数都会给我一个段错误,但是如果我不使用...

c posix valgrind
1个回答
0
投票

我想出了答案。事实证明,在取消映射后,我仍在尝试访问tbl结构中的变量。因此,要解决此问题,我刚刚在函数中创建了可变符,并在取消映射之前从tbl结构中保存了我需要的内容。

© www.soinside.com 2019 - 2024. All rights reserved.