【问题标题】:C: Copying a smaller section of memory onto a larger one without knowing the smaller ones size, as in realloc()C:在不知道较小的大小的情况下将较小的内存部分复制到较大的内存中,如 realloc()
【发布时间】:2013-10-02 09:33:26
【问题描述】:

realloc函数(c),它只占用内存的new部分的长度,如何复制old(更小,强制出现问题的情况) 部分内存到 一个? (这是假设它需要,例如,找不到与 old 块相邻的内存来扩展它)

如果它从较小的部分复制完整大小(第二个 arg 到 realloc),它会从无效内存中读取,对吗?

谢谢, J

编辑:说明一个极端示例的代码:

int main ( void ) {
  unsigned int i=0;
  void *test_ptr1, *test_ptr2;

  // this first bit just finds the size of the available heap, ignore it if you wish
  do {
    free(test_ptr1); 
    printf("%u\n",i);
    i+=1073741824; // 1GiB
  } while ((test_ptr1 = malloc(i)));
  i-=1073741824;
  do {
    free(test_ptr1); 
    printf("%u\n",i);
    i+=1048576; // 1MiB
  } while ((test_ptr1 = malloc(i)));
  i-=1048576;
  do {
    free(test_ptr1); 
     printf("%u\n",i);
     i+=1024; // 1KiB
  } while ((test_ptr1 = malloc(i)));
  i-=1024;
  do {
    free(test_ptr1);
    printf("%u\n",i); 
    i+=128; // 128B
  } while ((test_ptr1 = malloc(i)));
  i-=128;
  do {
    free(test_ptr1);
    printf("%u\n",i); 
    i++; // 1B
  } while ((test_ptr1 = malloc(i)));
  i--;

  // i is now equal to the size of the available heap (I think...)

  test_ptr1 = calloc(i-1, 1); // calloc all but one byte of the available heap
  test_ptr2 = malloc(1); // malloc the reamining byte
  printf("proving calloc: %u\n", ((char *)test_ptr1)[i-2]); // outputs 0, this might be a point of weakness int this program, if this is optimised in any way it fails to demonstrate the effect
  *(char *)test_ptr2 = 'c'; // initialise the byte to 'c'
  free(test_ptr1); // free the vast majority of the heap
  if ((test_ptr1 = realloc(test_ptr2, i-1))) { // realloc the one byte to the space taken up by the previous calloc that was freed in the previous line
    printf("realloc success: %c\n", *(char *)test_ptr1); // outputs c, but whats in the rest of this memory section? and more informatively, where was it coppied from?
    getc(stdin);
    free(test_ptr1);
    free(test_ptr2);
    return 0; 
  } else {
    printf("realloc failed\n");
    free(test_ptr2);
    return -1;
  }
}

输出:

1945305043
1945305044
1945305045
1945305046
1945305047
1945305048
1945305049
1945305050
1945305051
1945305052
1945305053
1945305054
1945305055
1945305056
proving calloc: 0
realloc success: c

【问题讨论】:

标签: memory memory-management memcpy realloc


【解决方案1】:

如果它从 更小的部分,它会从无效的内存中读取,对吧?

没错,看看文档:

内存块的内容被保留到较小的那个 新旧尺寸,即使块被移动到新位置。 如果 新大小越大,新分配部分的值是 不确定。

【讨论】:

  • 好的,谢谢,但它如何知道新部分中有多少不确定? (这样它就不会从旧部分复制这部分并运行到无效内存中)这个值将是 new_size-old_size 但它不知道 old_size 的值(或者它知道吗?)
  • 不知道!它需要一个指向内存块开头的指针,然后简单地“剪切”给定的大小!
  • 所以如果我理解正确的话,新部分中的“不确定”内存将与旧部分相邻的无效内存具有相同的值?这不是安全漏洞吗?再次感谢
  • 是的,但是 realloc 的主要目的是改变内存块的大小。文档说:该函数可能会将内存块移动到新位置...
  • 如果我会发生什么:分配除了一点点堆(最后),然后分配那一点点,释放非常大的部分并重新分配较小的座位以填充较大的部分;这会失败,填充来自另一个进程的数据,还是??
猜你喜欢
  • 2020-08-13
  • 1970-01-01
  • 2011-07-10
  • 1970-01-01
  • 1970-01-01
  • 2018-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多