int main()
{
double (*arr)[COLS] = (double*)malloc(sizeof(*arr) * ROWS);
assert(arr!= NULL);
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
arr[i][j] = 0.0;
}
}
//diagonal
for (int i = 0; i < ROWS; i++)
{
arr[i][i] = 4;
}
//SUB diagonal
for (int i = 1; i < ROWS; i++)
{
arr[i][i - 1] = -1;
}
//top diagonal
for (int i = 0; i < ROWS; i++)
{
arr[i][i + 1] = -1;
}
//printing the whole array
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
printf("%lf ", arr[i][j]);
}
printf("\n");
}
printf("###################\n");
//RHS
double* b = malloc(sizeof(double) * ROWS);
assert(b != NULL);
for (int j = 0; j < ROWS; j++) {
b[j] = 1;
}
for (int j = 0; j < ROWS; j++) {
printf("%lf\n", b[j]);
}
printf("--------------------\n");
//x_old
double* x_old = malloc(sizeof(double) * ROWS);
assert(x_old != NULL);
for (int j = 0; j < ROWS; j++) {
x_old[j] = 0.0;
}
for (int j = 0; j < ROWS; j++) {
printf("%lf\n", x_old[j]);
}
printf("******************\n");
//x_new
double* x_new = malloc(sizeof(double) * ROWS);
assert(x_new != NULL);
for (int j = 0; j < ROWS; j++) {
x_new[j] = 0.0;
}
for (int j = 0; j < ROWS; j++) {
printf("%lf\n", x_new[j]);
}
printf("^^^^^^^^^^^^^^^^^^^^^\n");
free((double*)arr);
free(b);
free(x_old);
free(x_new);
return 0;
}
和第二个版本
int main()
{
//allocation
double** arr = malloc(ROWS * sizeof(*arr));//pointer to an array with rows
if(arr != NULL){
for (int i = 0; i < ROWS; i++) {
//allocate memory for each row
arr[i] = malloc(COLS * sizeof(*arr[i]));
assert(arr[i] != NULL);
}
}
//diagonal
for (int i = 0; i < ROWS; i++)
{
arr[i][i] = 4;
}
//subdiagonal
for (int i = 1; i < ROWS; i++)
{
arr[i][i - 1] = -1;
}
//top diagonal
for (int i = 0; i < ROWS; i++)
{
arr[i][i + 1] = -1;
}
//printing the whole array
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
printf("%lf ", arr[i][j]);
}
printf("\n");
}
printf("###################\n");
//RHS
double* b= malloc(sizeof(double) * ROWS);
assert(b != NULL);
for (int j = 0; j < ROWS; j++) {
b[j] = 1;
}
for (int j = 0; j < ROWS; j++) {
printf("%lf\n", b[j]);
}
printf("--------------------\n");
//x_old
double* x_old = malloc(sizeof(double) * ROWS);
assert(x_old != NULL);
for (int j = 0; j < ROWS; j++) {
x_old[j] = 0.0;
}
for (int j = 0; j < ROWS; j++) {
printf("%lf\n", x_old[j]);
}
printf("******************\n");
//x_new
double* x_new = malloc(sizeof(double) * ROWS);
assert(x_new != NULL);
for (int j = 0; j < ROWS; j++) {
x_new[j] = 0.0;
}
for (int j = 0; j < ROWS; j++) {
printf("%lf\n", x_new[j]);
}
printf("^^^^^^^^^^^^^^^^^^^^^\n");
free(x_new);
free(x_old);
free(b);
//in this loop the mistake
for(int i=0;i<ROWS;i++){
if(array[i] != NULL){
free(array[i]);
arr[i] = NULL;
}
}
free(arr);
return 0;
}
the output of valgrind in both cases
==9955==
==9955== HEAP SUMMARY:
==9955== in use at exit: 1,050 bytes in 33 blocks
==9955== total heap usage: 35 allocs, 2 frees, 2,074 bytes allocated
==9955==
==9955== 27 bytes in 1 blocks are still reachable in loss record 1 of 4
==9955== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==9955== by 0x491458E: strdup (strdup.c:42)
==9955== by 0x10F43C: ??? (in /usr/bin/dash)
==9955== by 0x11EB69: ??? (in /usr/bin/dash)
==9955== by 0x10CB65: ??? (in /usr/bin/dash)
==9955== by 0x4895D8F: (below main) (libc_start_call_main.h:58)
==9955==
==9955== 31 bytes in 1 blocks are still reachable in loss record 2 of 4
==9955== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==9955== by 0x11E154: ??? (in /usr/bin/dash)
==9955== by 0x11EB69: ??? (in /usr/bin/dash)
==9955== by 0x10CB65: ??? (in /usr/bin/dash)
==9955== by 0x4895D8F: (below main) (libc_start_call_main.h:58)
==9955==
==9955== 32 bytes in 1 blocks are still reachable in loss record 3 of 4
==9955== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==9955== by 0x11E004: ??? (in /usr/bin/dash)
==9955== by 0x11EB44: ??? (in /usr/bin/dash)
==9955== by 0x10CB65: ??? (in /usr/bin/dash)
==9955== by 0x4895D8F: (below main) (libc_start_call_main.h:58)
==9955==
==9955== 960 bytes in 30 blocks are still reachable in loss record 4 of 4
==9955== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==9955== by 0x11E004: ??? (in /usr/bin/dash)
==9955== by 0x11EADF: ??? (in /usr/bin/dash)
==9955== by 0x10CB65: ??? (in /usr/bin/dash)
==9955== by 0x4895D8F: (below main) (libc_start_call_main.h:58)
==9955==
==9955== LEAK SUMMARY:
==9955== definitely lost: 0 bytes in 0 blocks
==9955== indirectly lost: 0 bytes in 0 blocks
==9955== possibly lost: 0 bytes in 0 blocks
==9955== still reachable: 1,050 bytes in 33 blocks
==9955== suppressed: 0 bytes in 0 blocks
==9955==
==9955== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
我建议不要使用 C,除非您被迫拥有最低公分母接口。您将能够使用像
Eigen
和 Armadillo
这样的 C++ 库来完成类似的事情,而无需手动分配内存,而且它们的速度甚至会与容易出错的重新发明轮子一样快。
不要将
malloc
的返回值投射到 C 中。
考虑使用
memset
来初始化 C 中的值(或使用可以使用构造函数自动初始化的 C++)。
您发布的 Valgrind 日志适用于您的 shell,而不是您的测试 exe。您需要做两件事之一。
修改您的包装器脚本,以便它在 Valgrind 中运行您的测试 exe。
或者运行 Valgrind,以便它也跟踪子进程。比如说
valgrind --trace-children=yes --log-file=memcheck.%p.log wrapper.dsh
这将为每个进程生成一个日志文件。您需要找到哪一个适合您的测试 exe,然后查看它。