回复 第5楼 的 doctorjxd:
事实远比你想像的要复杂,R也不是你想的那样邪恶。看下面的例子:
> x = 1:10<br />
> tracemem(x)<br />
[1] "<0x0db83e08>"<br />
><br />
> for(i in 1:10)<br />
+ {<br />
+ x[i] = i<br />
+ print(tracemem(x))<br />
+ }<br />
[1] "<0x0db83e08>"<br />
[1] "<0x0db83e08>"<br />
[1] "<0x0db83e08>"<br />
[1] "<0x0db83e08>"<br />
[1] "<0x0db83e08>"<br />
[1] "<0x0db83e08>"<br />
[1] "<0x0db83e08>"<br />
[1] "<0x0db83e08>"<br />
[1] "<0x0db83e08>"<br />
[1] "<0x0db83e08>"<br />
><br />
> x[1] = 1<br />
tracemem[0x0db83e08 -> 0x0d028db0]:<br />
> tracemem(x)<br />
[1] "<0x0d028db0>"<br />
</p>
这个例子说明,在循环赋值中,x的地址并没有发生改变,也就是说没有进行内存重分配。但是最后一句却发生了改变。为什么呢?
这里的邪恶之处在于,最初x = 1:10时,x是一个整数型向量,但后面x[1] = 1会使x向量变成double型,所以必须发生拷贝。而在循环中,i是整型变量,赋值给x时不会改变x的类型,内存也就没有发生改变。
总结起来就是三点:
1、改变向量类型一定会发生内存重分配;
2、改变向量长度一定会发生内存重分配;
3、上述两点都不变时,通常不会发生内存重分配。
所以,正确的做法依然是预先分配好长度。