2009-11-15 25 views
10

我想知道是否C或C++标准的保证,当realloc的是带一个小的(非零)大小的指针没有改变:如果新尺寸变小可以重新移动指针吗?

size_t n=1000; 
T*ptr=(T*)malloc(n*sizeof(T)); 
//<--do something useful (that won't touch/reallocate ptr of course) 
size_t n2=100;//or any value in [1,n-1] 
T*ptr2=(T*)realloc(ptr,n2*sizeof(T)); 
//<-- are we guaranteed that ptr2==ptr ? 

基本上,可以在OS决定自己,既然我们释放一个大内存块,他想利用所有的realloc来整理内存,并以某种方式移动ptr2?

回答

6

随着realloc,你绝对不能保证记忆将在哪里生活。我相信libc的默认malloc只会勉强地复制周围的内存,所以实际上你可能没问题。但不要指望它。

16

http://opengroup.org/onlinepubs/007908775/xsh/realloc.html

在与一个大小不等于0成功完成,realloc()的返回一个指针(可能移动)分配的空间。

不,不保证

+1

早先在那个页面上,它说:“realloc()函数将ptr指向的内存对象的大小更改为由size指定的大小。对象的内容将保持不变,直到new和如果内存对象的新大小需要移动对象,则先前实例化对象的空间将被释放。它并不排除议案,但相对不太可能。 – 2009-11-15 05:30:04

+1

是的,你仍然保证,以前的任何内存仍然会在那里,谢谢指出 – 2009-11-15 15:19:13

0

在Windows上,C运行时抓起一堆,然后从该堆分配内存。所以操作系统不会知道个别的内存分配,因此不会移动。

+1

这是不正确的。首先,Visual C运行时不直接调用操作系统堆实现。另一方面,HeapReAlloc()调用_does_移动事物。 – 2009-11-15 03:18:21

+1

你需要仔细检查你的文档。请参阅: http://msdn.microsoft.com/en-us/library/csd157zx.aspx CRT抓取单个操作系统堆以在内部使用。然后它会分配堆(意味着它不使用Win32堆调用来在该堆中执行分配) – DougN 2009-11-16 14:54:51

6

有没有保证realloc将返回相同的位置,期间。

+0

如果在某处明确声明,那将会很不错。不是说“X保证发生”与具体说明“X不保证发生”不同。 – RoG 2016-12-16 11:58:11

4

realloc不需要离开块地方,即使它会适合,而实际上最简单的存根实现是一个例子,其中也可能不:

  • malloc:致电sbrk
  • realloc:致电mallocmemcpy
  • free:no-op。

这听起来很荒谬,但有时对于嵌入式系统来说,像我刚才描述的实现实际上是最优的。

+0

另一个例子是一个实现,其中所有相邻的分配都是相同大小的块以避免分段。在这种情况下,一个32字节块不再与前面的4096字节块位于同一位置。 – 2011-05-11 21:01:49

+0

是的。另一个更高级的例子是一个实现,它检查要缩放的块的左侧邻居是否空闲,是否通过收缩在右侧创建重要的空闲块,结果大小是否“足够小“'memcpy'不是太贵......如果满足正确的条件,将块移到新的位置以避免碎片。 – 2011-05-11 22:41:41

2

在我看来,所有当前的答案(在这个答案的时候)并没有提到任何标准文件。

对于C++,我会参考Working Draft, Standard for Programming Language C++, Document Number: N3337, Date: 2012-01-16, Revises: N3291,根据https://isocpp.org/std/the-standard,它是非免费官方C++ 11标准文档中最接近的免费文档;在这里,我们找到13年6月20日C库

2的内容是相同的标准C库头, 有以下变化:在我看来,上市变化不相关的 题]。

所以现在我们必须参考C标准。

根据https://stackoverflow.com/a/83763/15485与非免费官方C11标准文件最接近的免费文件为Programming languages — C, N1570 Committee Draft — April 12, 2011 ISO/IEC 9899:201x;这里我们找到7.22.3。5 realloc函数

4 realloc函数返回一个指向新的对象(其 可以具有相同的值作为一个指针,指向旧的对象)或空 指针,如果新对象无法分配。

我不是英语为母语的人,所以由你来解释“可能有”的含义。

+4

我是英语母语人士(并且非常熟悉C标准)。带引号的文字表示新指针可能具有或不具有与旧指针相同的值,并不意味着这取决于大小。一个基本原理(在标准中没有说明)是一个实现可以在一个不同的位置分配一个较小的块来减少碎片并使未来的分配更有可能成功。为保证它在某些情况下不会移动,必须在标准中明确说明。事实并非如此。 – 2014-08-04 19:09:13