linux 内存越界判断_LINUX 共享内存越界

shmget的时候,我们能指定共享内存的size,当size越界的时候,会如何呢?

如下:

/*

* ShareMem.h

*

*  Created on: 2013-2-25

*      Author: coreycui

*/

#ifndef SHAREMEM_H_

#define SHAREMEM_H_

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

usingnamespacestd;

classShareMem {

public:

ShareMem(int_shmid);

boolcreate(intflag,intlen);

intgetSgmId()const;

char* attach();

booldettach();

virtual~ShareMem();

private:

intshmId;

boolisAttche;

char* addr;

};

#endif /* SHAREMEM_H_ */

/*

* ShareMem.h

*

* Created on: 2013-2-25

* Author: coreycui

*/

#ifndef SHAREMEM_H_

#define SHAREMEM_H_

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

class ShareMem {

public:

ShareMem(int _shmid);

bool create(int flag,int len);

int getSgmId() const;

char* attach();

bool dettach();

virtual ~ShareMem();

private:

int shmId;

bool isAttche;

char* addr;

};

#endif /* SHAREMEM_H_ */

/*

* ShareMem.cpp

*

*  Created on: 2013-2-25

*      Author: coreycui

*/

#include "ShareMem.h"

ShareMem::ShareMem(int_shmid) :

shmId(_shmid), isAttche(false), addr(0) {

}

boolShareMem::create(intflag,intlen) {

shmId = shmget(IPC_PRIVATE, len, flag);

if(shmId 

perror("share mem create error");

}

returntrue;

}

intShareMem::getSgmId()const{

returnshmId;

}

char* ShareMem::attach() {

isAttche =true;

char* addr = (char*) shmat(shmId, 0, 0);

if(addr 

perror("share mem attach error");

}

returnaddr;

}

boolShareMem::dettach() {

if(addr == 0 && isAttche) {

if(shmdt(addr) > 0) {

returntrue;

}else{

perror("share mem dettach error");

returnfalse;

}

}

returnfalse;

}

ShareMem::~ShareMem() {

dettach();

}

constoption options[] = { {"len", required_argument, NULL,'l'}, {"action", required_argument, NULL,'a'}, {"id",

required_argument, NULL,'i'}, {"msg", required_argument, NULL,'m'}, { 0, 0, 0, 0 } };

intmain(intargc,char**argv) {

charcFileName[128];

intlen;

intch;

intaction;

intid;

charmsg[10000];

while((ch = getopt_long(argc, argv,":l:a:i:", options, NULL)) != -1) {

switch(ch) {

case'l':

len = atoi(optarg);

break;

case'a':

action = atoi(optarg);

break;

case'i':

id = atoi(optarg);

break;

case'm':

strcpy(msg, optarg);

break;

default:

break;

}

}

cout <

//cout <

ShareMem mem(id);

intlockResult;

if(action == 0) {

mem.create(IPC_CREAT | 0666, len);

}

if(action == 1) {

char* addr = mem.attach();

cout <

cout <

strcpy(addr, msg);

}

if(action == 2) {

char* addr = mem.attach();

cout <

cout <

}

if(action == 3) {

for(inti=0;i<9999;i++){

msg[i]='a';

}

msg[9999]='\0';

char* addr = mem.attach();

cout <

strcpy(addr, msg);

}

cout <

pause();

}

/*

* ShareMem.cpp

*

* Created on: 2013-2-25

* Author: coreycui

*/

#include "ShareMem.h"

ShareMem::ShareMem(int _shmid) :

shmId(_shmid), isAttche(false), addr(0) {

}

bool ShareMem::create(int flag, int len) {

shmId = shmget(IPC_PRIVATE, len, flag);

if (shmId < 0) {

perror("share mem create error");

}

return true;

}

int ShareMem::getSgmId() const {

return shmId;

}

char* ShareMem::attach() {

isAttche = true;

char* addr = (char*) shmat(shmId, 0, 0);

if (addr < (char*) 0) {

perror("share mem attach error");

}

return addr;

}

bool ShareMem::dettach() {

if (addr == 0 && isAttche) {

if (shmdt(addr) > 0) {

return true;

} else {

perror("share mem dettach error");

return false;

}

}

return false;

}

ShareMem::~ShareMem() {

dettach();

}

const option options[] = { { "len", required_argument, NULL, 'l' }, { "action", required_argument, NULL, 'a' }, { "id",

required_argument, NULL, 'i' }, { "msg", required_argument, NULL, 'm' }, { 0, 0, 0, 0 } };

int main(int argc, char **argv) {

char cFileName[128];

int len;

int ch;

int action;

int id;

char msg[10000];

while ((ch = getopt_long(argc, argv, ":l:a:i:", options, NULL)) != -1) {

switch (ch) {

case 'l':

len = atoi(optarg);

break;

case 'a':

action = atoi(optarg);

break;

case 'i':

id = atoi(optarg);

break;

case 'm':

strcpy(msg, optarg);

break;

default:

break;

}

}

cout << "len:" << len << " action:" << action << " id:" << id << " msg:" << msg << endl;

//cout << "pageSize:" << PAGE_SIZE << endl;

ShareMem mem(id);

int lockResult;

if (action == 0) {

mem.create(IPC_CREAT | 0666, len);

}

if (action == 1) {

char* addr = mem.attach();

cout << "sizeof:" << strlen(addr) << endl;

cout << "msg sizeof" << strlen(msg) << endl;

strcpy(addr, msg);

}

if (action == 2) {

char* addr = mem.attach();

cout << "len.addr:" << strlen(addr) << endl;

cout << "addr:" << addr << endl;

}

if (action == 3) {

for(int i=0;i<9999;i++){

msg[i]='a';

}

msg[9999]='\0';

char* addr = mem.attach();

cout << "msg sizeof" << strlen(msg) << endl;

strcpy(addr, msg);

}

cout << lockResult << endl;

pause();

}

之上是对共享内存的封装,首先我们建立一块共享内存:

./shareMem --action=0 --len=2 --msg=helloworld --id=0

------ Shared Memory Segments --------

key        shmid      owner      perms      bytes      nattch     status

0x00005feb 0          admin     666        12000      3

0x00005fe7 32769      admin     666        524288     2

0x00005fe8 65538      admin     666        2097152    1

0x0003022a 131075     admin     777        2072       1

0x0003022b 163844     admin     777        5603392    1

0x00030227 196613     admin     777        221248     1

0x73010002 262150     admin     666        8          0

0x29481458 327688     mqq       644        114744     0

0x29481456 360457     mqq       644        11380552   0

0x29481457 393226     mqq       644        8020508    0

0x000033b0 425995     mqq       666        114688     0

0x00000000 589839     coreycui  666        2          0

对数据进行超过两个字节的write:

./shareMem --action=1 --len=2 --msg=helloworld --id=557070

后进行read,发现一切正常。

是不是shm对越界不做判断了?多出的字节写到了哪里呢?其实不然,shm的分配会自动补全到系统的PAGESIZE,32bit的机器上一般都是4096,不妨,我们写入10000字节。果然发生了段错误。所以这里我们必须做出判断。

bool ShareMem::getInfo(shmid_ds* buf) {

return shmctl(this->shmId, IPC_STAT, buf);

}

所以使用之前,我们必须得到内存块的大小,帮助我们更方便和安全的使用这块内存:

if (action == 4) { shmid_ds info; mem.getInfo(&info); cout << "shm seg len:" << info.shm_segsz << endl; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值