The checking logic would be refactored into an aspect file, as follows:
after(void * s) : (call($ malloc(...)) || call($ calloc(...)) || call($ realloc(...))) && result(s) { char * result = (char *)(s); if (result == NULL) { /* routine to handle the case when memory allocation fails */ } }
Now, the core program looks as follows:
... int *x ; x = (int *)malloc(sizeof(int) * 4); <--- dynamic memory allocation /* routine for handling the normal case */ ...
例子:
文件:mal.acc
#include <stdio.h>
after(void * s) : (call($ malloc(...)) || call($ calloc(...)) || call($ realloc(...)))
&& result(s) {
char * result = (char *)(s);
if (result != NULL) {
printf(" aspectC:Memory Allocation Success !
");
}
else{
printf(" aspectC:Memory Allocation Faile !
");
}
}
文件mal.c:
#include <stdio.h>
#include <malloc.h>
void t1()
{
int *x ;
printf(" core code:hehe !
");
x = (int *)malloc(sizeof(int) * 4);
printf(" core code:hehe ! !
");
}
int main()
{
t1();
int *x ;
printf(" core code:hehe ! !
");
x = (int *)malloc(sizeof(int) * 4);
printf(" core code:hehe ! !
");
return 0;
}