1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the library                         */
4    	/*          BMS --- Block Memory Shell                                       */
5    	/*                                                                           */
6    	/*  Copyright (c) 2002-2023 Zuse Institute Berlin (ZIB)                      */
7    	/*                                                                           */
8    	/*  Licensed under the Apache License, Version 2.0 (the "License");          */
9    	/*  you may not use this file except in compliance with the License.         */
10   	/*  You may obtain a copy of the License at                                  */
11   	/*                                                                           */
12   	/*      http://www.apache.org/licenses/LICENSE-2.0                           */
13   	/*                                                                           */
14   	/*  Unless required by applicable law or agreed to in writing, software      */
15   	/*  distributed under the License is distributed on an "AS IS" BASIS,        */
16   	/*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17   	/*  See the License for the specific language governing permissions and      */
18   	/*  limitations under the License.                                           */
19   	/*                                                                           */
20   	/*  You should have received a copy of the Apache-2.0 license                */
21   	/*  along with SCIP; see the file LICENSE. If not visit scipopt.org.         */
22   	/*                                                                           */
23   	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24   	
25   	/**@file   memory.h
26   	 * @brief  memory allocation routines
27   	 * @author Tobias Achterberg
28   	 * @author Gerald Gamrath
29   	 * @author Marc Pfetsch
30   	 */
31   	
32   	/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33   	
34   	#ifndef __BMS_MEMORY_H__
35   	#define __BMS_MEMORY_H__
36   	
37   	#include <limits.h>
38   	#include <stdlib.h>
39   	#include <stddef.h>
40   	
41   	/*
42   	 * include build configuration flags
43   	 */
44   	#include "scip/config.h"
45   	#include "scip/scip_export.h"
46   	
47   	#ifdef __cplusplus
48   	
49   	
50   	/* special thanks to Daniel Junglas for following template and macros */
51   	
52   	template<typename T> T* docast(T*, void *v);
53   	template<typename T> T* docast(T*, void *v) { return reinterpret_cast<T*>(v); }
54   	
55   	/* For C++11, we can easily check whether the types for memory functions like BMSduplicateXYZArray() are equal. */
56   	#if __cplusplus > 199711L
57   	#include <type_traits>
58   	
59   	/* the following adds a type check for the parameters, used in ASSIGNCHECK below */
60   	template<typename T1, typename T2> T1* docastcheck(T1* v1, void* v, T2* v2)
61   	{
62   	   typedef typename std::remove_const<T1>::type t1;
63   	   typedef typename std::remove_const<T2>::type t2;
64   	   static_assert(std::is_same<t1, t2>::value, "need equal types");
65   	   return reinterpret_cast<T1*>(v);
66   	}
67   	#else
68   	/* for older compilers do nothing */
69   	template<typename T1, typename T2> T1* docastcheck(T1* v1, void* v, T2* v2) { return reinterpret_cast<T1*>(v); }
70   	#endif
71   	
72   	
73   	extern "C" {
74   	
75   	#define ASSIGN(pointerstarstar, voidstarfunction) (*(pointerstarstar) = docast(*(pointerstarstar), (voidstarfunction)))
76   	#define ASSIGNCHECK(pointerstarstar, voidstarfunction, origpointer) (*(pointerstarstar) = docastcheck(*(pointerstarstar), (voidstarfunction), (origpointer)))
77   	
78   	#else
79   	
80   	#define ASSIGN(pointerstarstar, voidstarfunction) (*(pointerstarstar) = (voidstarfunction))
81   	#define ASSIGNCHECK(pointerstarstar, voidstarfunction, origpointer) (*(pointerstarstar) = (voidstarfunction))
82   	
83   	#endif
84   	
85   	/*
86   	 * Define the macro SCIP_EXPORT depending if the OS is Windows or not
87   	 */
88   	#ifndef SCIP_EXPORT
89   	
90   	#if defined(_WIN32) || defined(_WIN64)
91   	#define SCIP_EXPORT __declspec(dllexport)
92   	#elif defined(__GNUC__) && __GNUC__ >= 4
93   	#define SCIP_EXPORT __attribute__((__visibility__("default")))
94   	#else
95   	#define SCIP_EXPORT
96   	#endif
97   	
98   	#endif
99   	
100  	/* define if not already existing to make file independent from def.h */
101  	#ifndef SCIP_UNUSED
102  	#define SCIP_UNUSED(x) ((void) (x))
103  	#endif
104  	
105  	
106  	/*************************************************************************************
107  	 * Standard Memory Management
108  	 *
109  	 * In debug mode, these methods extend malloc() and free() by logging all currently
110  	 * allocated memory elements in an allocation list. This can be used as a simple leak
111  	 * detection.
112  	 *************************************************************************************/
113  	
114  	/* Note: values that are passed as a size_t parameter are first converted to ptrdiff_t to be sure that negative numbers
115  	 * are extended to the larger size. Then they are converted to size_t. Thus, negative numbers are converted to very
116  	 * large size_t values. This is then checked within the functions. */
117  	
118  	#define BMSallocMemory(ptr)                   ASSIGN((ptr), BMSallocMemory_call( sizeof(**(ptr)), __FILE__, __LINE__ ))
119  	#define BMSallocClearMemory(ptr)              ASSIGN((ptr), BMSallocClearMemory_call((size_t)(1), sizeof(**(ptr)), __FILE__, __LINE__ ))
120  	#define BMSallocMemorySize(ptr,size)          ASSIGN((ptr), BMSallocMemory_call( (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ ))
121  	#define BMSallocMemoryCPP(size)               BMSallocMemory_call( (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ )
122  	#define BMSallocClearMemorySize(ptr,size)     ASSIGN((ptr), BMSallocClearMemory_call((size_t)(1), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ ))
123  	#define BMSallocMemoryArray(ptr,num)          ASSIGN((ptr), BMSallocMemoryArray_call((size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__ ))
124  	#define BMSallocMemoryArrayCPP(num,size)      BMSallocMemoryArray_call( (size_t)(ptrdiff_t)(num), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ )
125  	#define BMSallocClearMemoryArray(ptr,num)     ASSIGN((ptr), BMSallocClearMemory_call((size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__ ))
126  	#define BMSreallocMemorySize(ptr,size)        ASSIGN((ptr), BMSreallocMemory_call((void*)(*(ptr)), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ ))
127  	#define BMSreallocMemoryArray(ptr,num)        ASSIGN((ptr), BMSreallocMemoryArray_call( *(ptr), (size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__ ))
128  	
129  	#define BMSclearMemory(ptr)                   BMSclearMemory_call( (void*)(ptr), sizeof(*(ptr)) )
130  	#define BMSclearMemoryArray(ptr, num)         BMSclearMemory_call( (void*)(ptr), (size_t)(ptrdiff_t)(num)*sizeof(*(ptr)) )
131  	#define BMSclearMemorySize(ptr, size)         BMSclearMemory_call( (void*)(ptr), (size_t)(ptrdiff_t)(size) )
132  	
133  	#define BMScopyMemory(ptr, source)            BMScopyMemory_call( (void*)(ptr), (const void*)(source), sizeof(*(ptr)) )
134  	#define BMScopyMemoryArray(ptr, source, num)  BMScopyMemory_call( (void*)(ptr), (const void*)(source), (size_t)(ptrdiff_t)(num)*sizeof(*(ptr)) )
135  	#define BMScopyMemorySize(ptr, source, size)  BMScopyMemory_call( (void*)(ptr), (const void*)(source), (size_t)(ptrdiff_t)(size) )
136  	
137  	#define BMSmoveMemory(ptr, source)            BMSmoveMemory_call( (void*)(ptr), (const void*)(source), sizeof(*(ptr)) )
138  	#define BMSmoveMemoryArray(ptr, source, num)  BMSmoveMemory_call( (void*)(ptr), (const void*)(source), (size_t)(ptrdiff_t)(num) * sizeof(*(ptr)) )
139  	#define BMSmoveMemorySize(ptr, source, size)  BMSmoveMemory_call( (void*)(ptr), (const void*)(source), (size_t)(ptrdiff_t)(size) )
140  	
141  	#define BMSduplicateMemory(ptr, source)       ASSIGN((ptr), BMSduplicateMemory_call( (const void*)(source), sizeof(**(ptr)), __FILE__, __LINE__ ))
142  	#define BMSduplicateMemorySize(ptr, source, size) ASSIGN((ptr), BMSduplicateMemory_call( (const void*)(source), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ ))
143  	#define BMSduplicateMemoryArray(ptr, source, num) ASSIGNCHECK((ptr), BMSduplicateMemoryArray_call( (const void*)(source), (size_t)(ptrdiff_t)(num), \
144  	                                                  sizeof(**(ptr)), __FILE__, __LINE__ ), source)
145  	#define BMSfreeMemory(ptr)                    BMSfreeMemory_call( (void**)(ptr), __FILE__, __LINE__ )
146  	#define BMSfreeMemoryNull(ptr)                BMSfreeMemoryNull_call( (void**)(ptr), __FILE__, __LINE__ )
147  	#define BMSfreeMemoryArray(ptr)               BMSfreeMemory_call( (void**)(ptr), __FILE__, __LINE__ )
148  	#define BMSfreeMemoryArrayNull(ptr)           BMSfreeMemoryNull_call( (void**)(ptr), __FILE__, __LINE__ )
149  	#define BMSfreeMemorySize(ptr)                BMSfreeMemory_call( (void**)(ptr), __FILE__, __LINE__ )
150  	#define BMSfreeMemorySizeNull(ptr)            BMSfreeMemoryNull_call( (void**)(ptr), __FILE__, __LINE__ )
151  	
152  	#ifndef NDEBUG
153  	#define BMSgetPointerSize(ptr)                BMSgetPointerSize_call(ptr)
154  	#define BMSdisplayMemory()                    BMSdisplayMemory_call()
155  	#define BMScheckEmptyMemory()                 BMScheckEmptyMemory_call()
156  	#define BMSgetMemoryUsed()                    BMSgetMemoryUsed_call()
157  	#else
158  	#define BMSgetPointerSize(ptr)                0
159  	#define BMSdisplayMemory()                    /**/
160  	#define BMScheckEmptyMemory()                 /**/
161  	#define BMSgetMemoryUsed()                    0LL
162  	#endif
163  	
164  	/** allocates array and initializes it with 0; returns NULL if memory allocation failed */
165  	SCIP_EXPORT
166  	void* BMSallocClearMemory_call(
167  	   size_t                num,                /**< number of memory element to allocate */
168  	   size_t                typesize,           /**< size of memory element to allocate */
169  	   const char*           filename,           /**< source file where the allocation is performed */
170  	   int                   line                /**< line number in source file where the allocation is performed */
171  	   );
172  	
173  	/** allocates memory; returns NULL if memory allocation failed */
174  	SCIP_EXPORT
175  	void* BMSallocMemory_call(
176  	   size_t                size,               /**< size of memory element to allocate */
177  	   const char*           filename,           /**< source file where the allocation is performed */
178  	   int                   line                /**< line number in source file where the allocation is performed */
179  	   );
180  	
181  	/** allocates array; returns NULL if memory allocation failed */
182  	SCIP_EXPORT
183  	void* BMSallocMemoryArray_call(
184  	   size_t                num,                /**< number of components of array to allocate */
185  	   size_t                typesize,           /**< size of each component */
186  	   const char*           filename,           /**< source file where the allocation is performed */
187  	   int                   line                /**< line number in source file where the allocation is performed */
188  	   );
189  	
190  	/** allocates memory; returns NULL if memory allocation failed */
191  	SCIP_EXPORT
192  	void* BMSreallocMemory_call(
193  	   void*                 ptr,                /**< pointer to memory to reallocate */
194  	   size_t                size,               /**< new size of memory element */
195  	   const char*           filename,           /**< source file where the reallocation is performed */
196  	   int                   line                /**< line number in source file where the reallocation is performed */
197  	   );
198  	
199  	/** reallocates array; returns NULL if memory allocation failed */
200  	SCIP_EXPORT
201  	void* BMSreallocMemoryArray_call(
202  	   void*                 ptr,                /**< pointer to memory to reallocate */
203  	   size_t                num,                /**< number of components of array to allocate */
204  	   size_t                typesize,           /**< size of each component */
205  	   const char*           filename,           /**< source file where the reallocation is performed */
206  	   int                   line                /**< line number in source file where the reallocation is performed */
207  	   );
208  	
209  	/** clears a memory element (i.e. fills it with zeros) */
210  	SCIP_EXPORT
211  	void BMSclearMemory_call(
212  	   void*                 ptr,                /**< pointer to memory element */
213  	   size_t                size                /**< size of memory element */
214  	   );
215  	
216  	/** copies the contents of one memory element into another memory element */
217  	SCIP_EXPORT
218  	void BMScopyMemory_call(
219  	   void*                 ptr,                /**< pointer to target memory element */
220  	   const void*           source,             /**< pointer to source memory element */
221  	   size_t                size                /**< size of memory element to copy */
222  	   );
223  	
224  	/** moves the contents of one memory element into another memory element, should be used if both elements overlap,
225  	 *  otherwise BMScopyMemory is faster
226  	 */
227  	SCIP_EXPORT
228  	void BMSmoveMemory_call(
229  	   void*                 ptr,                /**< pointer to target memory element */
230  	   const void*           source,             /**< pointer to source memory element */
231  	   size_t                size                /**< size of memory element to copy */
232  	   );
233  	
234  	/** allocates memory and copies the contents of the given memory element into the new memory element */
235  	SCIP_EXPORT
236  	void* BMSduplicateMemory_call(
237  	   const void*           source,             /**< pointer to source memory element */
238  	   size_t                size,               /**< size of memory element to copy */
239  	   const char*           filename,           /**< source file where the duplication is performed */
240  	   int                   line                /**< line number in source file where the duplication is performed */
241  	   );
242  	
243  	/** allocates array and copies the contents of the given source array into the new array */
244  	SCIP_EXPORT
245  	void* BMSduplicateMemoryArray_call(
246  	   const void*           source,             /**< pointer to source memory element */
247  	   size_t                num,                /**< number of components of array to allocate */
248  	   size_t                typesize,           /**< size of each component */
249  	   const char*           filename,           /**< source file where the duplication is performed */
250  	   int                   line                /**< line number in source file where the duplication is performed */
251  	   );
252  	
253  	/** frees an allocated memory element and sets pointer to NULL */
254  	SCIP_EXPORT
255  	void BMSfreeMemory_call(
256  	   void**                ptr,                /**< pointer to pointer to memory element */
257  	   const char*           filename,           /**< source file where the deallocation is performed */
258  	   int                   line                /**< line number in source file where the deallocation is performed */
259  	   );
260  	
261  	/** frees an allocated memory element if pointer is not NULL and sets pointer to NULL */
262  	SCIP_EXPORT
263  	void BMSfreeMemoryNull_call(
264  	   void**                ptr,                /**< pointer to pointer to memory element */
265  	   const char*           filename,           /**< source file where the deallocation is performed */
266  	   int                   line                /**< line number in source file where the deallocation is performed */
267  	   );
268  	
269  	/** returns the size of an allocated memory element */
270  	SCIP_EXPORT
271  	size_t BMSgetPointerSize_call(
272  	   const void*           ptr                 /**< pointer to allocated memory */
273  	   );
274  	
275  	/** outputs information about currently allocated memory to the screen */
276  	SCIP_EXPORT
277  	void BMSdisplayMemory_call(
278  	   void
279  	   );
280  	
281  	/** displays a warning message on the screen, if allocated memory exists */
282  	SCIP_EXPORT
283  	void BMScheckEmptyMemory_call(
284  	   void
285  	   );
286  	
287  	/** returns total number of allocated bytes */
288  	SCIP_EXPORT
289  	long long BMSgetMemoryUsed_call(
290  	   void
291  	   );
292  	
293  	
294  	
295  	
296  	/********************************************************************
297  	 * Chunk Memory Management
298  	 *
299  	 * Efficient memory management for multiple objects of the same size
300  	 ********************************************************************/
301  	
302  	typedef struct BMS_ChkMem BMS_CHKMEM;           /**< collection of memory chunks of the same element size */
303  	
304  	
305  	#ifndef BMS_NOBLOCKMEM
306  	
307  	#define BMScreateChunkMemory(sz,isz,gbf)      BMScreateChunkMemory_call( (sz), (isz), (gbf), __FILE__, __LINE__ )
308  	#define BMSclearChunkMemory(mem)              BMSclearChunkMemory_call( (mem), __FILE__, __LINE__ )
309  	#define BMSdestroyChunkMemory(mem)            BMSdestroyChunkMemory_call( (mem), __FILE__, __LINE__ )
310  	
311  	#define BMSallocChunkMemory(mem,ptr)          ASSIGN((ptr), BMSallocChunkMemory_call((mem), sizeof(**(ptr)), __FILE__, __LINE__))
312  	#define BMSduplicateChunkMemory(mem, ptr, source) ASSIGN((ptr), BMSduplicateChunkMemory_call((mem), (const void*)(source), \
313  	                                                sizeof(**(ptr)), __FILE__, __LINE__ ))
314  	#define BMSfreeChunkMemory(mem,ptr)           BMSfreeChunkMemory_call( (mem), (void**)(ptr), sizeof(**(ptr)), __FILE__, __LINE__ )
315  	#define BMSfreeChunkMemoryNull(mem,ptr)       BMSfreeChunkMemoryNull_call( (mem), (void**)(ptr), sizeof(**(ptr)), __FILE__, __LINE__ )
316  	#define BMSgarbagecollectChunkMemory(mem)     BMSgarbagecollectChunkMemory_call(mem)
317  	#define BMSgetChunkMemoryUsed(mem)            BMSgetChunkMemoryUsed_call(mem)
318  	
319  	#else
320  	
321  	/* block memory management mapped to standard memory management */
322  	
323  	#define BMScreateChunkMemory(sz,isz,gbf)           (void*)(0x01) /* dummy to not return a NULL pointer */
324  	#define BMSclearChunkMemory(mem)                   /**/
325  	#define BMSclearChunkMemoryNull(mem)               /**/
326  	#define BMSdestroyChunkMemory(mem)                 /**/
327  	#define BMSdestroyChunkMemoryNull(mem)             /**/
328  	#define BMSallocChunkMemory(mem,ptr)               BMSallocMemory(ptr)
329  	#define BMSduplicateChunkMemory(mem, ptr, source)  BMSduplicateMemory(ptr,source)
330  	#define BMSfreeChunkMemory(mem,ptr)                BMSfreeMemory(ptr)
331  	#define BMSfreeChunkMemoryNull(mem,ptr)            BMSfreeMemoryNull(ptr)
332  	#define BMSgarbagecollectChunkMemory(mem)          /**/
333  	#define BMSgetChunkMemoryUsed(mem)                 0LL
334  	
335  	#endif
336  	
337  	
338  	/** aligns the given byte size corresponding to the minimal alignment for chunk and block memory */
339  	SCIP_EXPORT
340  	void BMSalignMemsize(
341  	   size_t*               size                /**< pointer to the size to align */
342  	   );
343  	
344  	/** checks whether the given size meets the alignment conditions for chunk and block memory  */
345  	SCIP_EXPORT
346  	int BMSisAligned(
347  	   size_t                size                /**< size to check for alignment */
348  	   );
349  	
350  	/** creates a new chunk block data structure */
351  	SCIP_EXPORT
352  	BMS_CHKMEM* BMScreateChunkMemory_call(
353  	   size_t                size,               /**< element size of the chunk block */
354  	   int                   initchunksize,      /**< number of elements in the first chunk of the chunk block */
355  	   int                   garbagefactor,      /**< garbage collector is called, if at least garbagefactor * avg. chunksize 
356  	                                              *   elements are free (-1: disable garbage collection) */
357  	   const char*           filename,           /**< source file of the function call */
358  	   int                   line                /**< line number in source file of the function call */
359  	   );
360  	
361  	/** clears a chunk block data structure */
362  	SCIP_EXPORT
363  	void BMSclearChunkMemory_call(
364  	   BMS_CHKMEM*           chkmem,             /**< chunk block */
365  	   const char*           filename,           /**< source file of the function call */
366  	   int                   line                /**< line number in source file of the function call */
367  	   );
368  	
369  	/** destroys and frees a chunk block data structure */
370  	SCIP_EXPORT
371  	void BMSdestroyChunkMemory_call(
372  	   BMS_CHKMEM**          chkmem,             /**< pointer to chunk block */
373  	   const char*           filename,           /**< source file of the function call */
374  	   int                   line                /**< line number in source file of the function call */
375  	   );
376  	
377  	/** allocates a memory element of the given chunk block */
378  	SCIP_EXPORT
379  	void* BMSallocChunkMemory_call(
380  	   BMS_CHKMEM*           chkmem,             /**< chunk block */
381  	   size_t                size,               /**< size of memory element to allocate (only needed for sanity check) */
382  	   const char*           filename,           /**< source file of the function call */
383  	   int                   line                /**< line number in source file of the function call */
384  	   );
385  	
386  	/** duplicates a given memory element by allocating a new element of the same chunk block and copying the data */
387  	SCIP_EXPORT
388  	void* BMSduplicateChunkMemory_call(
389  	   BMS_CHKMEM*           chkmem,             /**< chunk block */
390  	   const void*           source,             /**< source memory element */
391  	   size_t                size,               /**< size of memory element to allocate (only needed for sanity check) */
392  	   const char*           filename,           /**< source file of the function call */
393  	   int                   line                /**< line number in source file of the function call */
394  	   );
395  	
396  	/** frees a memory element of the given chunk block and sets pointer to NULL */
397  	SCIP_EXPORT
398  	void BMSfreeChunkMemory_call(
399  	   BMS_CHKMEM*           chkmem,             /**< chunk block */
400  	   void**                ptr,                /**< pointer to pointer to memory element to free */
401  	   size_t                size,               /**< size of memory element to allocate (only needed for sanity check) */
402  	   const char*           filename,           /**< source file of the function call */
403  	   int                   line                /**< line number in source file of the function call */
404  	   );
405  	
406  	/** frees a memory element of the given chunk block if pointer is not NULL and sets pointer to NULL */
407  	SCIP_EXPORT
408  	void BMSfreeChunkMemoryNull_call(
409  	   BMS_CHKMEM*           chkmem,             /**< chunk block */
410  	   void**                ptr,                /**< pointer to pointer to memory element to free */
411  	   size_t                size,               /**< size of memory element to allocate (only needed for sanity check) */
412  	   const char*           filename,           /**< source file of the function call */
413  	   int                   line                /**< line number in source file of the function call */
414  	   );
415  	
416  	/** calls garbage collection of chunk block and frees chunks without allocated memory elements */
417  	SCIP_EXPORT
418  	void BMSgarbagecollectChunkMemory_call(
419  	   BMS_CHKMEM*           chkmem              /**< chunk block */
420  	   );
421  	
422  	/** returns the number of allocated bytes in the chunk block */
423  	SCIP_EXPORT
424  	long long BMSgetChunkMemoryUsed_call(
425  	   const BMS_CHKMEM*     chkmem              /**< chunk block */
426  	   );
427  	
428  	
429  	
430  	
431  	/***********************************************************
432  	 * Block Memory Management
433  	 *
434  	 * Efficient memory management for objects of varying sizes
435  	 ***********************************************************/
436  	
437  	typedef struct BMS_BlkMem BMS_BLKMEM;           /**< block memory: collection of chunk blocks */
438  	
439  	#ifndef BMS_NOBLOCKMEM
440  	
441  	/* block memory methods for faster memory access */
442  	
443  	/* Note: values that are passed as a size_t parameter are first converted to ptrdiff_t to be sure that negative numbers
444  	 * are extended to the larger size. Then they are converted to size_t. Thus, negative numbers are converted to very
445  	 * large size_t values. This is then checked within the functions. */
446  	
447  	#define BMScreateBlockMemory(csz,gbf)         BMScreateBlockMemory_call( (csz), (gbf), __FILE__, __LINE__ )
448  	#define BMSclearBlockMemory(mem)              BMSclearBlockMemory_call( (mem), __FILE__, __LINE__ )
449  	#define BMSdestroyBlockMemory(mem)            BMSdestroyBlockMemory_call( (mem), __FILE__, __LINE__ )
450  	
451  	#define BMSallocBlockMemory(mem,ptr)          ASSIGN((ptr), BMSallocBlockMemory_call((mem), sizeof(**(ptr)), __FILE__, __LINE__))
452  	#define BMSallocClearBlockMemory(mem,ptr)     ASSIGN((ptr), BMSallocClearBlockMemory_call((mem), sizeof(**(ptr)), __FILE__, __LINE__))
453  	#define BMSallocBlockMemorySize(mem,ptr,size) ASSIGN((ptr), BMSallocBlockMemory_call((mem), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__))
454  	#define BMSallocBlockMemoryArray(mem,ptr,num) ASSIGN((ptr), BMSallocBlockMemoryArray_call((mem), (size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__))
455  	#define BMSallocClearBlockMemoryArray(mem,ptr,num) ASSIGN((ptr), BMSallocClearBlockMemoryArray_call((mem), (size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__))
456  	#define BMSreallocBlockMemorySize(mem,ptr,oldsize,newsize) ASSIGN((ptr), BMSreallocBlockMemory_call((mem), (void*)(*(ptr)), \
457  	                                                (size_t)(ptrdiff_t)(oldsize), (size_t)(ptrdiff_t)(newsize), __FILE__, __LINE__))
458  	#define BMSreallocBlockMemoryArray(mem,ptr,oldnum,newnum) ASSIGN((ptr), BMSreallocBlockMemoryArray_call((mem), (void*)(*(ptr)), \
459  	                                                (size_t)(ptrdiff_t)(oldnum), (size_t)(ptrdiff_t)(newnum), sizeof(**(ptr)), __FILE__, __LINE__))
460  	#define BMSduplicateBlockMemory(mem, ptr, source) ASSIGN((ptr), BMSduplicateBlockMemory_call((mem), (const void*)(source), \
461  	                                                sizeof(**(ptr)), __FILE__, __LINE__ ))
462  	#define BMSduplicateBlockMemoryArray(mem, ptr, source, num) ASSIGNCHECK((ptr), BMSduplicateBlockMemoryArray_call( (mem), (const void*)(source), \
463  	                                                (size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__ ), source)
464  	
465  	#define BMSfreeBlockMemory(mem,ptr)           BMSfreeBlockMemory_call( (mem), (void**)(ptr), sizeof(**(ptr)), __FILE__, __LINE__ )
466  	#define BMSfreeBlockMemoryNull(mem,ptr)       BMSfreeBlockMemoryNull_call( (mem), (void**)(ptr), sizeof(**(ptr)), __FILE__, __LINE__ )
467  	#define BMSfreeBlockMemoryArray(mem,ptr,num)  BMSfreeBlockMemory_call( (mem), (void**)(ptr), (num)*sizeof(**(ptr)), __FILE__, __LINE__ )
468  	#define BMSfreeBlockMemoryArrayNull(mem,ptr,num) BMSfreeBlockMemoryNull_call( (mem), (void**)(ptr), (num)*sizeof(**(ptr)), __FILE__, __LINE__ )
469  	#define BMSfreeBlockMemorySize(mem,ptr,size)  BMSfreeBlockMemory_call( (mem), (void**)(ptr), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ )
470  	#define BMSfreeBlockMemorySizeNull(mem,ptr,size) BMSfreeBlockMemory_call( (mem), (void**)(ptr), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ )
471  	
472  	#define BMSgarbagecollectBlockMemory(mem)     BMSgarbagecollectBlockMemory_call(mem)
473  	#define BMSgetBlockMemoryAllocated(mem)       BMSgetBlockMemoryAllocated_call(mem)
474  	#define BMSgetBlockMemoryUsed(mem)            BMSgetBlockMemoryUsed_call(mem)
475  	#define BMSgetBlockMemoryUnused(mem)          BMSgetBlockMemoryUnused_call(mem)
476  	#define BMSgetBlockMemoryUsedMax(mem)         BMSgetBlockMemoryUsedMax_call(mem)
477  	#define BMSgetBlockMemoryUnusedMax(mem)       BMSgetBlockMemoryUnusedMax_call(mem)
478  	#define BMSgetBlockMemoryAllocatedMax(mem)    BMSgetBlockMemoryAllocatedMax_call(mem)
479  	#define BMSgetBlockPointerSize(mem,ptr)       BMSgetBlockPointerSize_call((mem), (ptr))
480  	#define BMSdisplayBlockMemory(mem)            BMSdisplayBlockMemory_call(mem)
481  	#define BMSblockMemoryCheckEmpty(mem)         BMScheckEmptyBlockMemory_call(mem)
482  	
483  	#else
484  	
485  	/* block memory management mapped to standard memory management */
486  	
487  	#define BMScreateBlockMemory(csz,gbf)                        (SCIP_UNUSED(csz), SCIP_UNUSED(gbf), (void*)(0x01)) /* dummy to not return a NULL pointer */
488  	#define BMSclearBlockMemory(mem)                             SCIP_UNUSED(mem)
489  	#define BMSclearBlockMemoryNull(mem)                         SCIP_UNUSED(mem)
490  	#define BMSdestroyBlockMemory(mem)                           SCIP_UNUSED(mem)
491  	#define BMSdestroyBlockMemoryNull(mem)                       SCIP_UNUSED(mem)
492  	#define BMSallocBlockMemory(mem,ptr)                         (SCIP_UNUSED(mem), BMSallocMemory(ptr))
493  	#define BMSallocClearBlockMemory(mem,ptr)                    (SCIP_UNUSED(mem), BMSallocClearMemory(ptr))
494  	#define BMSallocBlockMemoryArray(mem,ptr,num)                (SCIP_UNUSED(mem), BMSallocMemoryArray(ptr,num))
495  	#define BMSallocClearBlockMemoryArray(mem,ptr,num)           (SCIP_UNUSED(mem), BMSallocClearMemoryArray(ptr,num))
496  	#define BMSallocBlockMemorySize(mem,ptr,size)                (SCIP_UNUSED(mem), BMSallocMemorySize(ptr,size))
497  	#define BMSreallocBlockMemoryArray(mem,ptr,oldnum,newnum)    (SCIP_UNUSED(mem), SCIP_UNUSED(oldnum), BMSreallocMemoryArray(ptr,newnum))
498  	#define BMSreallocBlockMemorySize(mem,ptr,oldsize,newsize)   (SCIP_UNUSED(mem), SCIP_UNUSED(oldsize), BMSreallocMemorySize(ptr,newsize))
499  	#define BMSduplicateBlockMemory(mem, ptr, source)            (SCIP_UNUSED(mem), BMSduplicateMemory(ptr,source))
500  	#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)  (SCIP_UNUSED(mem), BMSduplicateMemoryArray(ptr,source,num))
501  	#define BMSfreeBlockMemory(mem,ptr)                          (SCIP_UNUSED(mem), BMSfreeMemory(ptr))
502  	#define BMSfreeBlockMemoryNull(mem,ptr)                      (SCIP_UNUSED(mem), BMSfreeMemoryNull(ptr))
503  	#define BMSfreeBlockMemoryArray(mem,ptr,num)                 (SCIP_UNUSED(mem), SCIP_UNUSED(num), BMSfreeMemoryArray(ptr))
504  	#define BMSfreeBlockMemoryArrayNull(mem,ptr,num)             (SCIP_UNUSED(mem), SCIP_UNUSED(num), BMSfreeMemoryArrayNull(ptr))
505  	#define BMSfreeBlockMemorySize(mem,ptr,size)                 (SCIP_UNUSED(mem), SCIP_UNUSED(size), BMSfreeMemory(ptr))
506  	#define BMSfreeBlockMemorySizeNull(mem,ptr,size)             (SCIP_UNUSED(mem), SCIP_UNUSED(size), BMSfreeMemoryNull(ptr))
507  	#define BMSgarbagecollectBlockMemory(mem)                    SCIP_UNUSED(mem)
508  	#define BMSgetBlockMemoryAllocated(mem)                      (SCIP_UNUSED(mem), 0LL)
509  	#define BMSgetBlockMemoryUsed(mem)                           (SCIP_UNUSED(mem), 0LL)
510  	#define BMSgetBlockMemoryUnused(mem)                         (SCIP_UNUSED(mem), 0LL)
511  	#define BMSgetBlockMemoryUsedMax(mem)                        (SCIP_UNUSED(mem), 0LL)
512  	#define BMSgetBlockMemoryUnusedMax(mem)                      (SCIP_UNUSED(mem), 0LL)
513  	#define BMSgetBlockMemoryAllocatedMax(mem)                   (SCIP_UNUSED(mem), 0LL)
514  	#define BMSgetBlockPointerSize(mem,ptr)                      (SCIP_UNUSED(mem), SCIP_UNUSED(ptr), 0)
515  	#define BMSdisplayBlockMemory(mem)                           SCIP_UNUSED(mem)
516  	#define BMSblockMemoryCheckEmpty(mem)                        (SCIP_UNUSED(mem), 0LL)
517  	
518  	#endif
519  	
520  	
521  	/** creates a block memory allocation data structure */
522  	SCIP_EXPORT
523  	BMS_BLKMEM* BMScreateBlockMemory_call(
524  	   int                   initchunksize,      /**< number of elements in the first chunk of each chunk block */
525  	   int                   garbagefactor,      /**< garbage collector is called, if at least garbagefactor * avg. chunksize 
526  	                                              *   elements are free (-1: disable garbage collection) */
527  	   const char*           filename,           /**< source file of the function call */
528  	   int                   line                /**< line number in source file of the function call */
529  	   );
530  	
531  	/** frees all chunk blocks in the block memory */
532  	SCIP_EXPORT
533  	void BMSclearBlockMemory_call(
534  	   BMS_BLKMEM*           blkmem,             /**< block memory */
535  	   const char*           filename,           /**< source file of the function call */
536  	   int                   line                /**< line number in source file of the function call */
537  	   );
538  	
539  	/** clears and deletes block memory */
540  	SCIP_EXPORT
541  	void BMSdestroyBlockMemory_call(
542  	   BMS_BLKMEM**          blkmem,             /**< pointer to block memory */
543  	   const char*           filename,           /**< source file of the function call */
544  	   int                   line                /**< line number in source file of the function call */
545  	   );
546  	
547  	/** allocates memory in the block memory pool */
548  	SCIP_EXPORT
549  	void* BMSallocBlockMemory_call(
550  	   BMS_BLKMEM*           blkmem,             /**< block memory */
551  	   size_t                size,               /**< size of memory element to allocate */
552  	   const char*           filename,           /**< source file of the function call */
553  	   int                   line                /**< line number in source file of the function call */
554  	   );
555  	
556  	/** allocates memory in the block memory pool and clears it */
557  	SCIP_EXPORT
558  	void* BMSallocClearBlockMemory_call(
559  	   BMS_BLKMEM*           blkmem,             /**< block memory */
560  	   size_t                size,               /**< size of memory element to allocate */
561  	   const char*           filename,           /**< source file of the function call */
562  	   int                   line                /**< line number in source file of the function call */
563  	   );
564  	
565  	/** allocates array in the block memory pool */
566  	SCIP_EXPORT
567  	void* BMSallocBlockMemoryArray_call(
568  	   BMS_BLKMEM*           blkmem,             /**< block memory */
569  	   size_t                num,                /**< size of array to be allocated */
570  	   size_t                typesize,           /**< size of each component */
571  	   const char*           filename,           /**< source file of the function call */
572  	   int                   line                /**< line number in source file of the function call */
573  	   );
574  	
575  	/** allocates array in the block memory pool and clears it */
576  	SCIP_EXPORT
577  	void* BMSallocClearBlockMemoryArray_call(
578  	   BMS_BLKMEM*           blkmem,             /**< block memory */
579  	   size_t                num,                /**< size of array to be allocated */
580  	   size_t                typesize,           /**< size of each component */
581  	   const char*           filename,           /**< source file of the function call */
582  	   int                   line                /**< line number in source file of the function call */
583  	   );
584  	
585  	/** resizes memory element in the block memory pool and copies the data */
586  	SCIP_EXPORT
587  	void* BMSreallocBlockMemory_call(
588  	   BMS_BLKMEM*           blkmem,             /**< block memory */
589  	   void*                 ptr,                /**< memory element to reallocated */
590  	   size_t                oldsize,            /**< old size of memory element */
591  	   size_t                newsize,            /**< new size of memory element */
592  	   const char*           filename,           /**< source file of the function call */
593  	   int                   line                /**< line number in source file of the function call */
594  	   );
595  	
596  	/** resizes array in the block memory pool and copies the data */
597  	SCIP_EXPORT
598  	void* BMSreallocBlockMemoryArray_call(
599  	   BMS_BLKMEM*           blkmem,             /**< block memory */
600  	   void*                 ptr,                /**< memory element to reallocated */
601  	   size_t                oldnum,             /**< old size of array */
602  	   size_t                newnum,             /**< new size of array */
603  	   size_t                typesize,           /**< size of each component */
604  	   const char*           filename,           /**< source file of the function call */
605  	   int                   line                /**< line number in source file of the function call */
606  	   );
607  	
608  	/** duplicates memory element in the block memory pool and copies the data */
609  	SCIP_EXPORT
610  	void* BMSduplicateBlockMemory_call(
611  	   BMS_BLKMEM*           blkmem,             /**< block memory */
612  	   const void*           source,             /**< memory element to duplicate */
613  	   size_t                size,               /**< size of memory elements */
614  	   const char*           filename,           /**< source file of the function call */
615  	   int                   line                /**< line number in source file of the function call */
616  	   );
617  	
618  	/** duplicates array in the block memory pool and copies the data */
619  	SCIP_EXPORT
620  	void* BMSduplicateBlockMemoryArray_call(
621  	   BMS_BLKMEM*           blkmem,             /**< block memory */
622  	   const void*           source,             /**< memory element to duplicate */
623  	   size_t                num,                /**< size of array to be duplicated */
624  	   size_t                typesize,           /**< size of each component */
625  	   const char*           filename,           /**< source file of the function call */
626  	   int                   line                /**< line number in source file of the function call */
627  	   );
628  	
629  	/** frees memory element in the block memory pool and sets pointer to NULL */
630  	SCIP_EXPORT
631  	void BMSfreeBlockMemory_call(
632  	   BMS_BLKMEM*           blkmem,             /**< block memory */
633  	   void**                ptr,                /**< pointer to pointer to memory element to free */
634  	   size_t                size,               /**< size of memory element */
635  	   const char*           filename,           /**< source file of the function call */
636  	   int                   line                /**< line number in source file of the function call */
637  	   );
638  	
639  	/** frees memory element in the block memory pool if pointer is not NULL and sets pointer to NULL */
640  	SCIP_EXPORT
641  	void BMSfreeBlockMemoryNull_call(
642  	   BMS_BLKMEM*           blkmem,             /**< block memory */
643  	   void**                ptr,                /**< pointer to pointer to memory element to free */
644  	   size_t                size,               /**< size of memory element */
645  	   const char*           filename,           /**< source file of the function call */
646  	   int                   line                /**< line number in source file of the function call */
647  	   );
648  	
649  	/** calls garbage collection of block memory, frees chunks without allocated memory elements, and frees
650  	 *  chunk blocks without any chunks
651  	 */
652  	SCIP_EXPORT
653  	void BMSgarbagecollectBlockMemory_call(
654  	   BMS_BLKMEM*           blkmem              /**< block memory */
655  	   );
656  	
657  	/** returns the number of allocated bytes in the block memory */
658  	SCIP_EXPORT
659  	long long BMSgetBlockMemoryAllocated_call(
660  	   const BMS_BLKMEM*     blkmem              /**< block memory */
661  	   );
662  	
663  	/** returns the number of used bytes in the block memory */
664  	SCIP_EXPORT
665  	long long BMSgetBlockMemoryUsed_call(
666  	   const BMS_BLKMEM*     blkmem              /**< block memory */
667  	   );
668  	
669  	/** returns the number of allocated but not used bytes in the block memory */
670  	SCIP_EXPORT
671  	long long BMSgetBlockMemoryUnused_call(
672  	   const BMS_BLKMEM*     blkmem              /**< block memory */
673  	   );
674  	
675  	/** returns the maximal number of used bytes in the block memory */
676  	SCIP_EXPORT
677  	long long BMSgetBlockMemoryUsedMax_call(
678  	   const BMS_BLKMEM*     blkmem              /**< block memory */
679  	   );
680  	
681  	/** returns the maximal number of allocated but not used bytes in the block memory */
682  	SCIP_EXPORT
683  	long long BMSgetBlockMemoryUnusedMax_call(
684  	   const BMS_BLKMEM*     blkmem              /**< block memory */
685  	   );
686  	
687  	/** returns the maximal number of allocated bytes in the block memory */
688  	long long BMSgetBlockMemoryAllocatedMax_call(
689  	   const BMS_BLKMEM*     blkmem              /**< block memory */
690  	   );
691  	
692  	/** returns the size of the given memory element; returns 0, if the element is not member of the block memory */
693  	SCIP_EXPORT
694  	size_t BMSgetBlockPointerSize_call(
695  	   const BMS_BLKMEM*     blkmem,             /**< block memory */
696  	   const void*           ptr                 /**< memory element */
697  	   );
698  	
699  	/** outputs allocation diagnostics of block memory */
700  	SCIP_EXPORT
701  	void BMSdisplayBlockMemory_call(
702  	   const BMS_BLKMEM*     blkmem              /**< block memory */
703  	   );
704  	
705  	/** outputs error messages, if there are allocated elements in the block memory and returns number of unfreed bytes */
706  	SCIP_EXPORT
707  	long long BMScheckEmptyBlockMemory_call(
708  	   const BMS_BLKMEM*     blkmem              /**< block memory */
709  	   );
710  	
711  	
712  	
713  	
714  	
715  	/***********************************************************
716  	 * Buffer Memory Management
717  	 *
718  	 * Efficient memory management for temporary objects
719  	 ***********************************************************/
720  	
721  	typedef struct BMS_BufMem BMS_BUFMEM;        /**< buffer memory for temporary objects */
722  	
723  	/* Note: values that are passed as a size_t parameter are first converted to ptrdiff_t to be sure that negative numbers
724  	 * are extended to the larger size. Then they are converted to size_t. Thus, negative numbers are converted to very
725  	 * large size_t values. This is then checked within the functions. */
726  	
727  	#define BMSallocBufferMemory(mem,ptr)        ASSIGN((ptr), BMSallocBufferMemory_call((mem), sizeof(**(ptr)), __FILE__, __LINE__))
728  	#define BMSallocBufferMemorySize(mem,ptr,size) ASSIGN((ptr), BMSallocBufferMemory_call((mem), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__))
729  	#define BMSreallocBufferMemorySize(mem,ptr,size) \
730  	                                             ASSIGN((ptr), BMSreallocBufferMemory_call((mem), (void*)(*(ptr)), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__))
731  	#define BMSallocBufferMemoryArray(mem,ptr,num) ASSIGN((ptr), BMSallocBufferMemoryArray_call((mem), (size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__))
732  	#define BMSallocClearBufferMemoryArray(mem,ptr,num) ASSIGN((ptr), BMSallocClearBufferMemoryArray_call((mem), (size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__))
733  	#define BMSreallocBufferMemoryArray(mem,ptr,num) ASSIGN((ptr), BMSreallocBufferMemoryArray_call((mem), (void*)(*(ptr)), (size_t)(ptrdiff_t)(num), \
734  	                                                 sizeof(**(ptr)), __FILE__, __LINE__))
735  	#define BMSduplicateBufferMemory(mem,ptr,source,size) \
736  	                                             ASSIGN((ptr), BMSduplicateBufferMemory_call((mem), (const void*)(source), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__))
737  	#define BMSduplicateBufferMemoryArray(mem,ptr,source,num) ASSIGNCHECK((ptr), BMSduplicateBufferMemoryArray_call((mem), \
738  	                                                 (const void*)(source), (size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__), source)
739  	
740  	#define BMSfreeBufferMemory(mem,ptr)         BMSfreeBufferMemory_call((mem), (void**)(ptr), __FILE__, __LINE__)
741  	#define BMSfreeBufferMemoryNull(mem,ptr)     BMSfreeBufferMemoryNull_call((mem), (void**)(ptr), __FILE__, __LINE__)
742  	#define BMSfreeBufferMemoryArray(mem,ptr)    BMSfreeBufferMemory_call((mem), (void**)(ptr), __FILE__, __LINE__)
743  	#define BMSfreeBufferMemoryArrayNull(mem,ptr) BMSfreeBufferMemoryNull_call((mem), (void**)(ptr), __FILE__, __LINE__)
744  	#define BMSfreeBufferMemorySize(mem,ptr)     BMSfreeBufferMemory_call((mem), (void**)(ptr), __FILE__, __LINE__);
745  	#define BMSfreeBufferMemorySizeNull(mem,ptr) BMSfreeBufferMemoryNull_call((mem), (void**)(ptr), __FILE__, __LINE__)
746  	
747  	#define BMScreateBufferMemory(fac,init,clean) BMScreateBufferMemory_call((fac), (init), (clean), __FILE__, __LINE__)
748  	#define BMSdestroyBufferMemory(mem)          BMSdestroyBufferMemory_call((mem), __FILE__, __LINE__)
749  	
750  	
751  	/** creates memory buffer storage */
752  	SCIP_EXPORT
753  	BMS_BUFMEM* BMScreateBufferMemory_call(
754  	   double                arraygrowfac,       /**< memory growing factor for dynamically allocated arrays */
755  	   int                   arraygrowinit,      /**< initial size of dynamically allocated arrays */
756  	   unsigned int          clean,              /**< should the memory blocks in the buffer be initialized to zero? */
757  	   const char*           filename,           /**< source file of the function call */
758  	   int                   line                /**< line number in source file of the function call */
759  	   );
760  	
761  	/** destroys buffer memory */
762  	SCIP_EXPORT
763  	void BMSdestroyBufferMemory_call(
764  	   BMS_BUFMEM**          buffer,             /**< pointer to memory buffer storage */
765  	   const char*           filename,           /**< source file of the function call */
766  	   int                   line                /**< line number in source file of the function call */
767  	   );
768  	
769  	/** set arraygrowfac */
770  	SCIP_EXPORT
771  	void BMSsetBufferMemoryArraygrowfac(
772  	   BMS_BUFMEM*           buffer,             /**< pointer to memory buffer storage */
773  	   double                arraygrowfac        /**< memory growing factor for dynamically allocated arrays */
774  	   );
775  	
776  	/** set arraygrowinit */
777  	SCIP_EXPORT
778  	void BMSsetBufferMemoryArraygrowinit(
779  	   BMS_BUFMEM*           buffer,             /**< pointer to memory buffer storage */
780  	   int                   arraygrowinit       /**< initial size of dynamically allocated arrays */
781  	   );
782  	
783  	/** allocates the next unused buffer */
784  	SCIP_EXPORT
785  	void* BMSallocBufferMemory_call(
786  	   BMS_BUFMEM*           buffer,             /**< memory buffer storage */
787  	   size_t                size,               /**< minimal required size of the buffer */
788  	   const char*           filename,           /**< source file of the function call */
789  	   int                   line                /**< line number in source file of the function call */
790  	   );
791  	
792  	/** allocates the next unused buffer array */
793  	SCIP_EXPORT
794  	void* BMSallocBufferMemoryArray_call(
795  	   BMS_BUFMEM*           buffer,             /**< memory buffer storage */
796  	   size_t                num,                /**< size of array to be allocated */
797  	   size_t                typesize,           /**< size of components */
798  	   const char*           filename,           /**< source file of the function call */
799  	   int                   line                /**< line number in source file of the function call */
800  	   );
801  	
802  	/** allocates the next unused buffer and clears it */
803  	SCIP_EXPORT
804  	void* BMSallocClearBufferMemoryArray_call(
805  	   BMS_BUFMEM*           buffer,             /**< memory buffer storage */
806  	   size_t                num,                /**< size of array to be allocated */
807  	   size_t                typesize,           /**< size of components */
808  	   const char*           filename,           /**< source file of the function call */
809  	   int                   line                /**< line number in source file of the function call */
810  	   );
811  	
812  	/** reallocates the buffer to at least the given size */
813  	SCIP_EXPORT
814  	void* BMSreallocBufferMemory_call(
815  	   BMS_BUFMEM*           buffer,             /**< memory buffer storage */
816  	   void*                 ptr,                /**< pointer to the allocated memory buffer */
817  	   size_t                size,               /**< minimal required size of the buffer */
818  	   const char*           filename,           /**< source file of the function call */
819  	   int                   line                /**< line number in source file of the function call */
820  	   );
821  	
822  	/** reallocates an array in the buffer to at least the given size */
823  	SCIP_EXPORT
824  	void* BMSreallocBufferMemoryArray_call(
825  	   BMS_BUFMEM*           buffer,             /**< memory buffer storage */
826  	   void*                 ptr,                /**< pointer to the allocated memory buffer */
827  	   size_t                num,                /**< size of array to be allocated */
828  	   size_t                typesize,           /**< size of components */
829  	   const char*           filename,           /**< source file of the function call */
830  	   int                   line                /**< line number in source file of the function call */
831  	   );
832  	
833  	/** allocates the next unused buffer and copies the given memory into the buffer */
834  	SCIP_EXPORT
835  	void* BMSduplicateBufferMemory_call(
836  	   BMS_BUFMEM*           buffer,             /**< memory buffer storage */
837  	   const void*           source,             /**< memory block to copy into the buffer */
838  	   size_t                size,               /**< minimal required size of the buffer */
839  	   const char*           filename,           /**< source file of the function call */
840  	   int                   line                /**< line number in source file of the function call */
841  	   );
842  	
843  	/** allocates an array in the next unused buffer and copies the given memory into the buffer */
844  	SCIP_EXPORT
845  	void* BMSduplicateBufferMemoryArray_call(
846  	   BMS_BUFMEM*           buffer,             /**< memory buffer storage */
847  	   const void*           source,             /**< memory block to copy into the buffer */
848  	   size_t                num,                /**< size of array to be allocated */
849  	   size_t                typesize,           /**< size of components */
850  	   const char*           filename,           /**< source file of the function call */
851  	   int                   line                /**< line number in source file of the function call */
852  	   );
853  	
854  	/** frees a buffer and sets pointer to NULL */
855  	SCIP_EXPORT
856  	void BMSfreeBufferMemory_call(
857  	   BMS_BUFMEM*           buffer,             /**< memory buffer storage */
858  	   void**                ptr,                /**< pointer to pointer to the allocated memory buffer */
859  	   const char*           filename,           /**< source file of the function call */
860  	   int                   line                /**< line number in source file of the function call */
861  	   );
862  	
863  	/** frees a buffer if pointer is not NULL and sets pointer to NULL */
864  	SCIP_EXPORT
865  	void BMSfreeBufferMemoryNull_call(
866  	   BMS_BUFMEM*           buffer,             /**< memory buffer storage */
867  	   void**                ptr,                /**< pointer to pointer to the allocated memory buffer */
868  	   const char*           filename,           /**< source file of the function call */
869  	   int                   line                /**< line number in source file of the function call */
870  	   );
871  	
872  	/** gets number of used buffers */
873  	SCIP_EXPORT
874  	size_t BMSgetNUsedBufferMemory(
875  	   BMS_BUFMEM*           buffer              /**< memory buffer storage */
876  	   );
877  	
878  	/** returns the number of allocated bytes in the buffer memory */
879  	SCIP_EXPORT
880  	long long BMSgetBufferMemoryUsed(
881  	   const BMS_BUFMEM*     bufmem              /**< buffer memory */
882  	   );
883  	
884  	/** outputs statistics about currently allocated buffers to the screen */
885  	SCIP_EXPORT
886  	void BMSprintBufferMemory(
887  	   BMS_BUFMEM*           buffer              /**< memory buffer storage */
888  	   );
889  	
890  	
891  	#ifdef __cplusplus
892  	}
893  	#endif
894  	
895  	#endif
896