1

メモリの新しいセクションの長さだけを取る realloc 関数 (c) は、メモリの古い(問題の状況を強制するために小さい) セクションを新しいセクションにどのようにコピーしますか? (これは、メモリを拡張するために古いブロックに隣接するメモリが見つからなかったため、必要があると想定しています)

より小さいセクションからフル サイズ (realloc への 2 番目の引数) をコピーすると、無効なメモリから読み取られますよね?

ありがとう、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
4

1 に答える 1

1

より小さいセクションからフル サイズ (realloc への 2 番目の引数) をコピーすると、無効なメモリから読み取られますよね?

そうです、ドキュメントを見てください:

メモリ ブロックの内容は、ブロックが新しい場所に移動された場合でも、新しいサイズと古いサイズの小さい方まで保持されます。新しいサイズがより大きい場合、新しく割り当てられた部分の値は不確定です。

于 2013-10-02T09:41:24.763 に答える