首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

深入点认识 malloc解决办法

2012-05-15 
深入点认识 mallocchar* pp (char*)malloc(n * sizeof(char))问题1:p为字符串,n为这个字符串中字符个

深入点认识 malloc
char* p;
p = (char*)malloc(n * sizeof(char));
问题1:p为字符串,n为这个字符串中字符个数,在申请时,我需不需要多申请一个即(n+1)用来放'\0'?

char* a;
char* b;
a = (char*)malloc(sizeof(char));
b = (char*)malloc(sizeof(char));
printf("a:%p b:%p\n"a,b);

输出:a:0x87bb008 b:0x87bb018
问题2:为什么a、b之间相差了10?
  malloc是对于一个变量是连续分配的吗?对于像a、b这样的内存也是连续的吗?
  开辟的是一个怎样的空间,如先开辟a,指针型,再开辟*a,char型,对吗,内存里结构图怎样的?
  如果我将char改成int,输出一样,这又作何解释呢?

问题3:如果超过了开辟的空间怎么办?开辟了空间后,我如何知道我开辟的空间有多大?如何查询如p以下还有多少空间可用?
 
希望能从原理上解释,能通过算法实现,尽量不要用到现成的函数!

问题4:malloc用起来还是感觉到很陌生,能否提点下,通常使用的malloc的要点、技巧,是怎么用的?

[解决办法]
在申请时,我需要多申请一个即(n+1)用来放'\0',这样是最好的,如果你不这样的话,比如strlen函数就不可能得到正确的答案了。
2 相差10有什么问题。C语言没有规定连续申请的内存必须保证在一起。只有规定a里面的内存是连续的而已。
3 超过了开辟的空间,那你就访问了非法内存了。这个一般都是要自己控制的。就好像你明知自己申请的内存为100字节,你却访问101,那你是明知故犯啊。你自己开辟的空间你会不知道有多大?这问题让我嘀咕了,malloc要么返回你申请的内存空间的首地址表示成功,要么返回null表示未成功。
内存有多少没有用,那就没有办法了。自己知道的。
[解决办法]
问题1,要的。

后面的建议你看看brk(),sbrk(),mmap()这几个系统调用或者库函数的具体实现。
[解决办法]
2,malloc开出来的空间不是连续的,不过你循环申请并且内存里没太多碎片的话还是有很大几率给连续的空间的.
3.属于指针越界的情况了,可能会立即core dump也可能什么都不发生
[解决办法]
补充一下为什么2个malloc相差0x10
因为malloc的实现,分配的空间是一个2的幂,这是为了更好的内存对齐
也就是a和b实际上是连续分配的,malloc占用了16个字节
[解决办法]

探讨

在申请时,我需要多申请一个即(n+1)用来放'\0',这样是最好的,如果你不这样的话,比如strlen函数就不可能得到正确的答案了。
2 相差10有什么问题。C语言没有规定连续申请的内存必须保证在一起。只有规定a里面的内存是连续的而已。
3 超过了开辟的空间,那你就访问了非法内存了。这个一般都是要自己控制的。就好像你明知自己申请的内存为100字节,你却访问101,那你是明知故犯啊。你自己开辟……

[解决办法]
C/C++ code
char* a;char* b;a = (char*)malloc(sizeof(char));b = (char*)malloc(sizeof(char));printf("a:%p b:%p\n"a,b);输出:a:00382F08 b:00382F38(随机的)我的却是相差30,我想这个和你的编译器有关吧。
[解决办法]
第一个问题,如果你的有效字符串中字符的个数是n个,那么就需要申请n+1个字符空间,这样多出的一个用于存放'\0';
第二个问题,相差10个是有问题的,不止10个,因为这是16进制数,所以相差的是16个字节。首先你需要明白的一个问题是,使用malloc申请的空间并不在栈上申请的,而是在堆上。但是int类型的指针变量实在函数栈上申请的,它们终归是变量,并且是局部的(如果在函数内部定义)。malloc是函数调用,它的返回值是在堆上申请的空间的首地址,返回值会存放于指针变量的空间里。所以指针会指向在堆上申请的空间。至于,为什么会相差16个字节。在堆上空间的申请是随机的,这与编译器有关。
第三个问题,malloc是属于动态申请空间,至于分配多少,这要根据需求来定。如果申请的空间后来发现少了,那么可以使用realloc申请更多的空间。申请多少有开发者来确定,而开发者就有需求来定了。
第四个问题,至于malloc的使用,不仅malloc,在C语言中还有realloc,alloc,free这些函数,这些函数是负责对堆上空间的申请和释放的函数。通过这些函数来管理堆上的空间,堆上的空间不想栈上那样会有编译器自动释放,而是由编程者自己申请和释放。至于用法,你可以去网上搜一搜。有一点,申请并不一定成功,使用后一定要释放。
[解决办法]
问题1:p为字符串,n为这个字符串中字符个数,在申请时,我需不需要多申请一个即(n+1)用来放'\0'?

char* a;
char* b;
a = (char*)malloc(sizeof(char));
b = (char*)malloc(sizeof(char));
printf("a:%p b:%p\n"a,b);

输出:a:0x87bb008 b:0x87bb018
问题2:为什么a、b之间相差了10?
malloc是对于一个变量是连续分配的吗?对于像a、b这样的内存也是连续的吗?
开辟的是一个怎样的空间,如先开辟a,指针型,再开辟*a,char型,对吗,内存里结构图怎样的?
如果我将char改成int,输出一样,这又作何解释呢?

问题3:如果超过了开辟的空间怎么办?开辟了空间后,我如何知道我开辟的空间有多大?如何查询如p以下还有多少空间可用?
 
希望能从原理上解释,能通过算法实现,尽量不要用到现成的函数!

问题4:malloc用起来还是感觉到很陌生,能否提点下,通常使用的malloc的要点、技巧,是怎么用的?


1: 需要。
2: 不是连续的,取决于堆的设计。不同的设计则顺序不同,而且现代的堆都要求输出的地址是4字节对齐,或者8字节对齐的。比如,伯克利DB实现的堆是从后往前分配,它的地址顺序通常是倒的。
3: 如果是超过了界限,就是堆越界。我认为,这是软件里最恐怖的事件,有一次我调试了3天才定位了一个堆越界,因为它越得很巧,导致VC++的堆检查没有报警,调试版也不出错,只有release版非调试运行才崩溃。你想知道你分配的堆块有多长,其实,很多堆都提供函数,返回堆块长度,但此函数不是标准的堆函数,所以,如果不是调试堆,最后不要出现在你的工程了。
4: 用用就好了。你还可以自己尝试练习着实现一个堆。

热点排行