我知道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
非常感谢任何帮助!
答案 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];
}
}
}