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