Programming Specification
1. Define variable return_code to record the function's status.
int return_code = 0;
2. Define the exit flag: exit_flag, which is used by goto. This flag is defined at the end of function body. The content of exit_flag includes free memory and return the status of function.
exit_flag: if(m_a) free(m_a); if(m_b) free(m_b); if(m_c) free(m_c); if(m_d) free(m_d); return return_code;
3. Check the array formal parameters of function.
//check if (NULL == a) { return_code = -1; goto exit_flag; } if (NULL == b) { return_code = -1; goto exit_flag; }
4. Allocate memory
// allocate memory m_a = (float *) malloc(n * sizeof(float)); if(!m_a){ printf("Failed to allocate memory! \n"); return_code = -1; goto exit_flag; }
Example:
#define IN #define OUT int solve_tridiagonal_equation_thomas( IN int n, IN float a[], IN float b[], IN float c[], IN float d[], OUT float x[] ) { int return_code = 0; //check if (NULL == a) { return_code = -1; goto exit_flag; } if (NULL == b) { return_code = -1; goto exit_flag; } if (NULL == c) { return_code = -1; goto exit_flag; } if (NULL == d) { return_code = -1; goto exit_flag; } if (NULL == x) { return_code = -1; goto exit_flag; } int i = 0; float tmp = 0; float *m_a, *m_b, *m_c, *m_d; // allocate memory m_a = (float *) malloc(n * sizeof(float)); if(!m_a){ printf("Failed to allocate memory! \n"); return_code = -1; goto exit_flag; } m_b = (float *) malloc(n * sizeof(float)); if(!m_b){ printf("Failed to allocate memory! \n"); return_code = -1; goto exit_flag; } m_c = (float *) malloc(n * sizeof(float)); if(!m_c){ printf("Failed to allocate memory! \n"); return_code = -1; goto exit_flag; } m_d = (float *) malloc(n * sizeof(float)); if(!m_d){ printf("Failed to allocate memory! \n"); return_code = -1; goto exit_flag; } // diagonal dominant validation and copy data bool cond1 = (abs(b[0]) > abs(c[0])) && (abs(c[0]) > 0); bool cond2 = (abs(b[n-1]) > abs(a[n-1])) && (abs(a[n-1]) > 0); if(!(cond1 && cond2)) { printf("Matrix is Invalid! \n"); return_code = -2; goto exit_flag; } for(i = 1; i < n-1; ++i) { if(abs(b[i]) < abs(c[i]) + abs(c[i])) { printf("Matrix is NOT diagonal dominant! \n"); return_code = -2; goto exit_flag; } else{ m_a[i] = a[i]; m_b[i] = b[i]; m_c[i] = c[i]; m_d[i] = d[i]; } } memcpy(m_a, a, n * sizeof(float)); // forward elimination for(i = 1; i < n; ++i) { tmp = m_a[i] / m_b[i-1]; m_b[i] = m_b[i] - tmp * m_c[i-1]; m_d[i] = m_d[i] - tmp * m_d[i-1]; } // backward substitution x[n-1] = m_d[n-1] / m_b[n-1]; for(i = n-2; i >= 0; --i) { x[i] = (m_d[i] - m_c[i] * x[i+1]) / m_b[i]; } // free memory and exit exit_flag: if(m_a) free(m_a); if(m_b) free(m_b); if(m_c) free(m_c); if(m_d) free(m_d); return return_code; }