副标题#e#
问题:内存利用
有人写了一个将整数转换为字符串的函数:
char *itoa (int n)
{
char retbuf[20];
sprintf(retbuf, "%d", n);
return retbuf;
}
假如我挪用这个函数:char *str5 = itoa(5),str5会是什么功效呢?
谜底阐明:
谜底是不确定,可以确定的是必定不是我们想要的 “5”。
retbuf界说在函数体中,是一个局部变量,它的内存空间位于栈(stack)中的某个位置,其浸染范畴也仅限于在itoa()这个函数中。当itoa()函数退出时,retbuf在挪用栈中的内容将被收回,这时,这块内存地点大概存放此外内容。因此将retbuf这个局部变量返回给挪用者是达不到预期的目标的。
那么如何办理这个问题呢,不消担忧,要领不单有,并且还不止一个,下面就来叙述三种能办理这个问题的步伐:
1)、在itoa()函数内部界说一个static char retbuf[20],按照静态变量的特性,我们知道,这可以担保函数返回后retbuf的空间不会被收回,原因是函数内的静态变量并不是放在栈中,而是放在措施中一个叫“.bss”段的处所,这个处所的内容是不会因为函数退出而被收回的。
这种步伐确实能办理问题,可是这种步伐同时也导致了itoa()函数酿成了一个不行重入的函数(即不能担保沟通的输入必定有沟通的输出),别的, retbuf [] 中的内容会被下一次的挪用功效所替代,这种步伐不值得推荐。
2)、在itoa()函数内部用malloc() 为retbuf申请内存,并将功效存放个中,然后将retbuf返回给挪用者。由于此时retbuf位于堆(heap)中,也不会跟着函数返回而释放,因此可以到达我们的目标。
可是有这样一种环境需要留意:itoa()函数的挪用者在不需要retbuf的时候必需把它释放,不然就造成内存泄漏了,假如此函数和挪用函数都是同一小我私家所写,问题不大,但假如不是,则较量容易会疏漏此释放内存的操纵。
3)、将函数界说为char *itoa(int n, char *retbuf),且retbuf的空间由挪用者申请和释放,itoa()只是将转换功效存放到retbuf罢了。
这种步伐明明比第一、二种要领要好,既制止了要领1对函数的影响,也制止了要领2对内存分派释放的影响,是今朝一种较量通行的做法。
扩展阐明:
其实就这个问题自己而言,我想各人都可以立即想到谜底,要害在于对内存这种敏感资源的正确和公道地操作,下面临内存做一个简朴的阐明:
1)、措施中有差异的内存段,包罗:
.data – 已初始化全局/静态变量,在整个软件执行进程中有效;
.bss – 未初始化全局/静态变量,在整个软件执行进程中有效;
.stack – 函数挪用栈,个中的内容在函数执行期间有效,并由编译器认真分派和收回;
.heap – 堆,由措施显式分派和收回,假如不收回就是内存泄漏。
#p#副标题#e#
2)、本身利用的内存最好照旧本身申请和释放。
这可以说是一个内存分派和释放的原则,好比说上面办理步伐的第二种,由itoa()分派的内存,最后由挪用者释放,就不是一个很好的步伐,还不如用第三种,由挪用者本身申请和释放。别的这个原则尚有一层意思是说:假如你要利用一个指针,最好先确信它已经指向正当内存区了,假如没有就得本成分派,要不就是犯科指针会见。许多措施的致命错误都是会见一个没有指向正当内存区的指针,这也包罗空指针。
问题:内存分派 & sizeof
我利用sizeof来计较一个指针变量,我但愿获得这个指针变量所分派的内存块的巨细,可以吗?
Char *p = NULL;
int nMemSize = 0;
…
p = malloc(1024);
nMemSize = sizeof(p);
谜底与阐明:
谜底是达不到你的要求,sizeof只能汇报你指针自己占用的内存巨细。指针所指向的内存,假如是malloc分派的,sizeof 是没有步伐知道的。换句话说,malloc分派的内存是没有步伐向内存打点模块举办过后查询的,虽然你可以本身编写代码来维护。
问题:栈内存利用
下面措施运行有什么问题?
char *GetString(void)
{
char p[] = "hello world";
return p;// 编译器将提出告诫
}
void Test4(void)
{
char *str = NULL;
str = GetString();// str 的内容是垃圾
cout<< str << endl;
}
谜底与阐明:
返回栈内存,内存大概被销毁,也大概不被销毁,可是,出了浸染域之后已被标志成可被系统利用,所以,参差不齐不行知内容,虽然,返回的指针的内容,应该是稳定的,非凡时候是有用的,好比,可以用来探测系统内存分派纪律等等。
问题:内存利用相关编程类型
我想尽大概地制止内存利用上的问题,有什么捷径吗?
谜底与阐明:
#p#分页标题#e#
除非做一件从没有人做过的工作,不然,都是有捷径可言的,那就是站在前人的肩膀上,此刻各个大公司都有本身的编码类型,这些类型凝结了许多的履历和教导,有较高的利用代价,鉴于这些类型在网上传播许多,这里我就不再列出了,感乐趣的,推荐参考林锐的《高质量C/C++编程指南》。