@@ -853,6 +853,59 @@ pub unsafe trait AllocRef {
853
853
result
854
854
}
855
855
856
+ /// Behaves like `realloc`, but also ensures that the new contents
857
+ /// are set to zero before being returned.
858
+ ///
859
+ /// # Safety
860
+ ///
861
+ /// This function is unsafe for the same reasons that `realloc` is.
862
+ ///
863
+ /// # Errors
864
+ ///
865
+ /// Returns `Err` only if the new layout
866
+ /// does not meet the allocator's size
867
+ /// and alignment constraints of the allocator, or if reallocation
868
+ /// otherwise fails.
869
+ ///
870
+ /// Implementations are encouraged to return `Err` on memory
871
+ /// exhaustion rather than panicking or aborting, but this is not
872
+ /// a strict requirement. (Specifically: it is *legal* to
873
+ /// implement this trait atop an underlying native allocation
874
+ /// library that aborts on memory exhaustion.)
875
+ ///
876
+ /// Clients wishing to abort computation in response to a
877
+ /// reallocation error are encouraged to call the [`handle_alloc_error`] function,
878
+ /// rather than directly invoking `panic!` or similar.
879
+ ///
880
+ /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
881
+ unsafe fn realloc_zeroed (
882
+ & mut self ,
883
+ ptr : NonNull < u8 > ,
884
+ layout : Layout ,
885
+ new_size : usize ,
886
+ ) -> Result < NonNull < u8 > , AllocErr > {
887
+ let old_size = layout. size ( ) ;
888
+
889
+ if new_size >= old_size {
890
+ if let Ok ( ( ) ) = self . grow_in_place_zeroed ( ptr, layout, new_size) {
891
+ return Ok ( ptr) ;
892
+ }
893
+ } else if new_size < old_size {
894
+ if let Ok ( ( ) ) = self . shrink_in_place ( ptr, layout, new_size) {
895
+ return Ok ( ptr) ;
896
+ }
897
+ }
898
+
899
+ // otherwise, fall back on alloc + copy + dealloc.
900
+ let new_layout = Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) ;
901
+ let result = self . alloc_zeroed ( new_layout) ;
902
+ if let Ok ( new_ptr) = result {
903
+ ptr:: copy_nonoverlapping ( ptr. as_ptr ( ) , new_ptr. as_ptr ( ) , cmp:: min ( old_size, new_size) ) ;
904
+ self . dealloc ( ptr, layout) ;
905
+ }
906
+ result
907
+ }
908
+
856
909
/// Behaves like `alloc`, but also ensures that the contents
857
910
/// are set to zero before being returned.
858
911
///
@@ -904,6 +957,31 @@ pub unsafe trait AllocRef {
904
957
self . alloc ( layout) . map ( |p| Excess ( p, usable_size. 1 ) )
905
958
}
906
959
960
+ /// Behaves like `alloc`, but also returns the whole size of
961
+ /// the returned block. For some `layout` inputs, like arrays, this
962
+ /// may include extra storage usable for additional data.
963
+ /// Also it ensures that the contents are set to zero before being returned.
964
+ ///
965
+ /// # Safety
966
+ ///
967
+ /// This function is unsafe for the same reasons that `alloc` is.
968
+ ///
969
+ /// # Errors
970
+ ///
971
+ /// Returning `Err` indicates that either memory is exhausted or
972
+ /// `layout` does not meet allocator's size or alignment
973
+ /// constraints, just as in `alloc`.
974
+ ///
975
+ /// Clients wishing to abort computation in response to an
976
+ /// allocation error are encouraged to call the [`handle_alloc_error`] function,
977
+ /// rather than directly invoking `panic!` or similar.
978
+ ///
979
+ /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
980
+ unsafe fn alloc_excess_zeroed ( & mut self , layout : Layout ) -> Result < Excess , AllocErr > {
981
+ let usable_size = self . usable_size ( & layout) ;
982
+ self . alloc_zeroed ( layout) . map ( |p| Excess ( p, usable_size. 1 ) )
983
+ }
984
+
907
985
/// Behaves like `realloc`, but also returns the whole size of
908
986
/// the returned block. For some `layout` inputs, like arrays, this
909
987
/// may include extra storage usable for additional data.
@@ -934,6 +1012,37 @@ pub unsafe trait AllocRef {
934
1012
self . realloc ( ptr, layout, new_size) . map ( |p| Excess ( p, usable_size. 1 ) )
935
1013
}
936
1014
1015
+ /// Behaves like `realloc`, but also returns the whole size of
1016
+ /// the returned block. For some `layout` inputs, like arrays, this
1017
+ /// may include extra storage usable for additional data.
1018
+ /// Also it ensures that the contents are set to zero before being returned.
1019
+ ///
1020
+ /// # Safety
1021
+ ///
1022
+ /// This function is unsafe for the same reasons that `realloc` is.
1023
+ ///
1024
+ /// # Errors
1025
+ ///
1026
+ /// Returning `Err` indicates that either memory is exhausted or
1027
+ /// `layout` does not meet allocator's size or alignment
1028
+ /// constraints, just as in `realloc`.
1029
+ ///
1030
+ /// Clients wishing to abort computation in response to a
1031
+ /// reallocation error are encouraged to call the [`handle_alloc_error`] function,
1032
+ /// rather than directly invoking `panic!` or similar.
1033
+ ///
1034
+ /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
1035
+ unsafe fn realloc_excess_zeroed (
1036
+ & mut self ,
1037
+ ptr : NonNull < u8 > ,
1038
+ layout : Layout ,
1039
+ new_size : usize ,
1040
+ ) -> Result < Excess , AllocErr > {
1041
+ let new_layout = Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) ;
1042
+ let usable_size = self . usable_size ( & new_layout) ;
1043
+ self . realloc_zeroed ( ptr, layout, new_size) . map ( |p| Excess ( p, usable_size. 1 ) )
1044
+ }
1045
+
937
1046
/// Attempts to extend the allocation referenced by `ptr` to fit `new_size`.
938
1047
///
939
1048
/// If this returns `Ok`, then the allocator has asserted that the
@@ -983,6 +1092,34 @@ pub unsafe trait AllocRef {
983
1092
if new_size <= u { Ok ( ( ) ) } else { Err ( CannotReallocInPlace ) }
984
1093
}
985
1094
1095
+ /// Behaves like `grow_in_place`, but also ensures that the new
1096
+ /// contents are set to zero before being returned.
1097
+ ///
1098
+ /// # Safety
1099
+ ///
1100
+ /// This function is unsafe for the same reasons that `grow_in_place` is.
1101
+ ///
1102
+ /// # Errors
1103
+ ///
1104
+ /// Returns `Err(CannotReallocInPlace)` when the allocator is
1105
+ /// unable to assert that the memory block referenced by `ptr`
1106
+ /// could fit `layout`.
1107
+ ///
1108
+ /// Note that one cannot pass `CannotReallocInPlace` to the `handle_alloc_error`
1109
+ /// function; clients are expected either to be able to recover from
1110
+ /// `grow_in_place` failures without aborting, or to fall back on
1111
+ /// another reallocation method before resorting to an abort.
1112
+ unsafe fn grow_in_place_zeroed (
1113
+ & mut self ,
1114
+ ptr : NonNull < u8 > ,
1115
+ layout : Layout ,
1116
+ new_size : usize ,
1117
+ ) -> Result < ( ) , CannotReallocInPlace > {
1118
+ self . grow_in_place ( ptr, layout, new_size) ?;
1119
+ ptr. as_ptr ( ) . add ( layout. size ( ) ) . write_bytes ( 0 , new_size - layout. size ( ) ) ;
1120
+ Ok ( ( ) )
1121
+ }
1122
+
986
1123
/// Attempts to shrink the allocation referenced by `ptr` to fit `new_size`.
987
1124
///
988
1125
/// If this returns `Ok`, then the allocator has asserted that the
0 commit comments