#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#define allocate( type, n ) malloc( sizeof(type) * n )
#define clear_allocate( type, n ) calloc( n, sizeof(type) )
// total rows initialized in pool
#define NUM_ROWS (size_t)100
#define HEIGHT (size_t)3
#define WIDTH (size_t)4
int main() {
typedef double Element;
typedef Element* Row;
typedef Row* Matrix;
_Bool allocate_successfully = true;
size_t failure_at = NUM_ROWS;
// handle of all rows
Row * allocated_rows = allocate( Row, NUM_ROWS );
assert( allocated_rows
!= NULL
); // fatal error // init each rows ( allocate memory needed )
for ( size_t i = 0; allocate_successfully && i != NUM_ROWS; ++i ) {
allocated_rows[ i ] = allocate( Element, WIDTH );
if ( allocated_rows[ i ] == NULL ) {
allocate_successfully = false;
failure_at = i;
}
}
if ( allocate_successfully == false )
goto after_use;
size_t next = 0;
Matrix a1 = allocate( Row, HEIGHT );
assert( a1
!= NULL
); // fatal error for ( size_t row = 0; row != HEIGHT; ++row ) {
a1[ row ] = allocated_rows[ next++ ];
}
Matrix a2 = allocate( Row, HEIGHT );
assert( a2
!= NULL
); // fatal error for ( size_t row = 0; row != HEIGHT; ++row ) {
a2[ row ] = allocated_rows[ next++ ];
}
after_use:
{
Matrix matrices[] = { a1, a2 };
for ( size_t i = 0; i != sizeof(matrices)/sizeof(matrices[0]); ++i )
// free the rows allocated in pool
for ( size_t i = 0; i != failure_at; ++i )
free( allocated_rows
[ i
] ); }
return EXIT_SUCCESS;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRkZWYuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkYm9vbC5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiAKI2RlZmluZSBhbGxvY2F0ZSggdHlwZSwgbiApIG1hbGxvYyggc2l6ZW9mKHR5cGUpICogbiApCiNkZWZpbmUgY2xlYXJfYWxsb2NhdGUoIHR5cGUsIG4gKSBjYWxsb2MoIG4sIHNpemVvZih0eXBlKSApCiAKLy8gdG90YWwgcm93cyBpbml0aWFsaXplZCBpbiBwb29sCiNkZWZpbmUgTlVNX1JPV1MgKHNpemVfdCkxMDAKIAojZGVmaW5lIEhFSUdIVCAoc2l6ZV90KTMKI2RlZmluZSBXSURUSCAoc2l6ZV90KTQKIAppbnQgbWFpbigpIHsKIAogICAgdHlwZWRlZiBkb3VibGUgRWxlbWVudDsKICAgIHR5cGVkZWYgRWxlbWVudCogUm93OwogICAgdHlwZWRlZiBSb3cqIE1hdHJpeDsKIAogICAgX0Jvb2wgYWxsb2NhdGVfc3VjY2Vzc2Z1bGx5ID0gdHJ1ZTsKICAgIHNpemVfdCBmYWlsdXJlX2F0ID0gTlVNX1JPV1M7CiAKICAgIC8vIGhhbmRsZSBvZiBhbGwgcm93cwogICAgUm93ICogYWxsb2NhdGVkX3Jvd3MgPSBhbGxvY2F0ZSggUm93LCBOVU1fUk9XUyApOwogICAgYXNzZXJ0KCBhbGxvY2F0ZWRfcm93cyAhPSBOVUxMICk7IC8vIGZhdGFsIGVycm9yCiAgICAvLyBpbml0IGVhY2ggcm93cyAoIGFsbG9jYXRlIG1lbW9yeSBuZWVkZWQgKQogICAgZm9yICggc2l6ZV90IGkgPSAwOyBhbGxvY2F0ZV9zdWNjZXNzZnVsbHkgJiYgaSAhPSBOVU1fUk9XUzsgKytpICkgewogCiAgICAgICAgYWxsb2NhdGVkX3Jvd3NbIGkgXSA9IGFsbG9jYXRlKCBFbGVtZW50LCBXSURUSCApOwogCiAgICAgICAgaWYgKCBhbGxvY2F0ZWRfcm93c1sgaSBdID09IE5VTEwgKSB7CiAgICAgICAgICAgIGFsbG9jYXRlX3N1Y2Nlc3NmdWxseSA9IGZhbHNlOwogICAgICAgICAgICBmYWlsdXJlX2F0ID0gaTsKICAgICAgICB9CiAgICB9CiAKICAgIGlmICggYWxsb2NhdGVfc3VjY2Vzc2Z1bGx5ID09IGZhbHNlICkKICAgICAgICBnb3RvIGFmdGVyX3VzZTsKIAogICAgc2l6ZV90IG5leHQgPSAwOwogICAgTWF0cml4IGExID0gYWxsb2NhdGUoIFJvdywgSEVJR0hUICk7CiAgICBhc3NlcnQoIGExICE9IE5VTEwgKTsgLy8gZmF0YWwgZXJyb3IKICAgIGZvciAoIHNpemVfdCByb3cgPSAwOyByb3cgIT0gSEVJR0hUOyArK3JvdyApIHsKICAgICAgICBhMVsgcm93IF0gPSBhbGxvY2F0ZWRfcm93c1sgbmV4dCsrIF07CiAgICB9CiAKICAgIE1hdHJpeCBhMiA9IGFsbG9jYXRlKCBSb3csIEhFSUdIVCApOwogICAgYXNzZXJ0KCBhMiAhPSBOVUxMICk7IC8vIGZhdGFsIGVycm9yCiAgICBmb3IgKCBzaXplX3Qgcm93ID0gMDsgcm93ICE9IEhFSUdIVDsgKytyb3cgKSB7CiAgICAgICAgYTJbIHJvdyBdID0gYWxsb2NhdGVkX3Jvd3NbIG5leHQrKyBdOwogICAgfQogCmFmdGVyX3VzZToKICAgIHsKICAgIE1hdHJpeCBtYXRyaWNlc1tdID0geyBhMSwgYTIgfTsKICAgIGZvciAoIHNpemVfdCBpID0gMDsgaSAhPSBzaXplb2YobWF0cmljZXMpL3NpemVvZihtYXRyaWNlc1swXSk7ICsraSApCiAgICAgICAgZnJlZSggbWF0cmljZXNbIGkgXSApOwogCiAgICAvLyBmcmVlIHRoZSByb3dzIGFsbG9jYXRlZCBpbiBwb29sCiAgICBmb3IgKCBzaXplX3QgaSA9IDA7IGkgIT0gZmFpbHVyZV9hdDsgKytpICkKICAgICAgICBmcmVlKCBhbGxvY2F0ZWRfcm93c1sgaSBdICk7CiAgICBmcmVlKCBhbGxvY2F0ZWRfcm93cyApOwogICAgfQogICAgCiAgICByZXR1cm4gRVhJVF9TVUNDRVNTOwp9