Seg Fault /使用大小为8的未初始化值

时间:2018-03-07 03:59:03

标签: c++ segmentation-fault valgrind dynamic-arrays

我知道Seg故障通常是由无效的内存访问引起的,所以我认为问题可能在于我如何初始化传递给split函数的2d动态数组。但是,我花了好几个小时来查看它,似乎无法找到问题。

使用valgrind我得到以下内容:

==31912== Command: ./Project1 Data.txt
==31912== 
==31912== Use of uninitialised value of size 8
==31912==    at 0x4016C6: split(long**, long**, long**, long, long) (in /home/tony/Project1)
==31912==    by 0x400E5F: main (in /home/tony/Project1)
==31912== 
==31912== Invalid read of size 8
==31912==    at 0x4016C9: split(long**, long**, long**, long, long) (in /home/tony/Project1)
==31912==    by 0x400E5F: main (in /home/tony/Project1)
==31912==  Address 0x41d7894956415741 is not stack'd, malloc'd or (recently) free'd
==31912== 
==31912== 
==31912== Process terminating with default action of signal 11 (SIGSEGV)
==31912==  General Protection Fault
==31912==    at 0x4016C9: split(long**, long**, long**, long, long) (in /home/tony/Project1)
==31912==    by 0x400E5F: main (in /home/tony/Project1)
==31912== 
==31912== HEAP SUMMARY:
==31912==     in use at exit: 1,248 bytes in 81 blocks
==31912==   total heap usage: 89 allocs, 8 frees, 97,119 bytes allocated
==31912== 
==31912== LEAK SUMMARY:
==31912==    definitely lost: 304 bytes in 1 blocks
==31912==    indirectly lost: 304 bytes in 38 blocks
==31912==      possibly lost: 0 bytes in 0 blocks
==31912==    still reachable: 640 bytes in 42 blocks
==31912==         suppressed: 0 bytes in 0 blocks
==31912== Rerun with --leak-check=full to see details of leaked memory
==31912== 
==31912== For counts of detected and suppressed errors, rerun with: -v
==31912== Use --track-origins=yes to see where uninitialised values come from
==31912== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

valgrind似乎认为的分裂功能是罪魁祸首:

void split(long** arr, long** arrL, long** arrR, long median, long size){   
//split data in half by x value -- takes in array sorted by x
    for (long i = 0; i < size -1; i++){
        if (i <= median){   //split data in half by x coord 
            arrL[i][0] = arr[i][0]; //x
            arrL[i][1] = arr[i][1]; //y
        }else{
            arrR[i][0] = arr[i][0];
            arrR[i][1] = arr[i][1];
        }
    }

}

在我的main函数中,我初始化数组,然后像这样调用split():

        arrL = new long*[median + 1];//add one to make sure there is enough room
        arrR = new long*[median + 1];
        for(long i = 0; i < median + 1; i++){
            arrL[i] = new long[1];
            arrR[i] = new long[1];
        }


    split(arr, arrL, arrR, median, size);   //splits data

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

仔细看看这一行(和类似的那些)。

arrL[i] = new long[1];

您分配了1个项目,因此arrL[i]的唯一有效索引为0.但在split函数中,您执行此操作:

arrL[i][1] = arr[i][1]; //y

这将访问超出范围的索引1

您应该分配2个项目,而不是1个。

arrL[i] = new long[2];

答案 1 :(得分:0)

l主要问题是你的arrL和arrR数组的大小是中位数,但在写入arrR时我会比中位数大。

调整arrL和arrR以包含size * long对象,或者arrR使用i-median作为索引,如下面的代码

void split(long** arr, long** arrL, long** arrR, long median, long size);

int _tmain(int argc, _TCHAR* argv[])
{
    int size = 10;
    int median = size / 2;

    long **arr, **arrL, **arrR;
    arr = new long*[size];
    for(long i = 0; i < size; i++){
        arr[i] = new long[2];
        arr[i][0] = i;
        arr[i][1] = i + 10;
    }

    arrL = new long*[median + 1];//add one to make sure there is enough room
    arrR = new long*[median + 1];
    for(int i = 0; i < median + 1; i++){
        arrL[i] = new long[2];
        arrR[i] = new long[2];
        arrL[i][0] = -1;
        arrL[i][1] = -1;
        arrR[i][0] = -1;
        arrR[i][1] = -1;
    }

    split(arr, arrL, arrR, median, size);

    for(int i = 0; i < median + 1; i++)
        printf("arrL %d = %ld %ld\n", i, arrL[i][0], arrL[i][1]);

    for(int i = 0; i < median + 1; i++)
        printf("arrR %d = %ld %ld\n", i, arrR[i][0], arrR[i][1]);

    return 0;
}

void split(long** arr, long** arrL, long** arrR, long median, long size){   
//split data in half by x value -- takes in array sorted by x
    for (int i = 0; i < size; i++){
        if (i < median){   //split data in half by x coord 
            arrL[i][0] = arr[i][0]; //x
            arrL[i][1] = arr[i][1]; //y
        }else{
            arrR[i - median][0] = arr[i][0];
            arrR[i - median][1] = arr[i][1];
        }
    }
}