简体   繁体   中英

I'm having trouble finding the segmentation fault?

I've written a program to perform mergesort on an array in C++. The program compiles fine, but when I run it, it says - "Segmentation fault (core dumped)" and quits. I've been trying to debug it but to no avail. I'm sure I've misused pointers somewhere (hence the segmentation fault) but can't place where. Could someone help me out? Thanks.

#include<iostream>
#include<queue>
#include<algorithm>
#include<math.h>
using namespace std;

void merge(int a[],int start, int middle, int end)
{
  int i;
  queue<int> buffer1;
  queue<int> buffer2;

  for(i = start; i<=middle; i++)
    buffer1.push(a[i]);

  for(i = middle+1; i<=end; i++)
    buffer2.push(a[i]);

  i = start;

  while((!buffer1.empty()) || (!buffer2.empty()))
    {
      if(buffer1.front() < buffer2.front())
    {
      a[i] = buffer1.front();
      buffer1.pop();
      i++;
    }

      else
    {
      a[i] = buffer2.front();
      buffer2.pop();
      i++;
    }
    }

  while(!buffer1.empty())
    {
      a[i] = buffer1.front();
      buffer1.pop();
      i++;
    }

  while(!buffer2.empty())
    {
      a[i] = buffer2.front();
      buffer2.pop();
      i++;
    }


}

void mergeSort(int a[], int start, int end)
{
  int middle;

  if(start<end)
    {
      middle = (start+end)/2;
      mergeSort(a,start,middle);
      mergeSort(a,middle+1,end);
      merge(a, start, middle, end);
    }

}

int main()
{
  int b[6] = {7,8,0,4,5,1},s = 0, e = 5;

  mergeSort(b,s,e);

  for(int i = 0; i<6; i++)
    cout<<b[i]<<endl;

}

Here is what the debugger is outputting -

execve("./q1", ["./q1"], [/* 63 vars */]) = 0
brk(0)                                  = 0x1cde000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fee90911000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=116033, ...}) = 0
mmap(NULL, 116033, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fee908f4000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/usr/lib/x86_64-linux-gnu/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \240\10\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=1566568, ...}) = 0
mmap(NULL, 3675328, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fee9036e000
mprotect(0x7fee904e1000, 2093056, PROT_NONE) = 0
mmap(0x7fee906e0000, 49152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x172000) = 0x7fee906e0000
mmap(0x7fee906ec000, 13504, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fee906ec000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360*\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=92504, ...}) = 0
mmap(NULL, 2188352, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fee90157000
mprotect(0x7fee9016d000, 2093056, PROT_NONE) = 0
mmap(0x7fee9036c000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x7fee9036c000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\v\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1869392, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fee908f3000
mmap(NULL, 3972864, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fee8fd8d000
mprotect(0x7fee8ff4d000, 2097152, PROT_NONE) = 0
mmap(0x7fee9014d000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c0000) = 0x7fee9014d000
mmap(0x7fee90153000, 16128, PROT_READ|PROT_WRITE, `enter code here`MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fee90153000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240U\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=1084840, ...}) = 0
mmap(NULL, 3174760, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fee8fa85000
mprotect(0x7fee8fb8c000, 2093056, PROT_NONE) = 0
mmap(0x7fee8fd8b000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x106000) = 0x7fee8fd8b000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fee908f2000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fee908f0000
arch_prctl(ARCH_SET_FS, 0x7fee908f0740) = 0
mprotect(0x7fee9014d000, 16384, PROT_READ) = 0
mprotect(0x7fee8fd8b000, 4096, PROT_READ) = 0
mprotect(0x7fee9036c000, 4096, PROT_READ) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fee908ef000
mprotect(0x7fee906e0000, 40960, PROT_READ) = 0
mprotect(0x604000, 4096, PROT_READ)     = 0
mprotect(0x7fee90913000, 4096, PROT_READ) = 0
munmap(0x7fee908f4000, 116033)          = 0
brk(0)                                  = 0x1cde000
brk(0x1d10000)                          = 0x1d10000
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault (core dumped)

Your while condition seems wrong. You are looping as long as one of the two containers are not empty and then subsequently calling the front() member function on them. You should probably be looping till both of them have elements in them, ie use && on line 21 instead of || .

So this line

while((!buffer1.empty()) || (!buffer2.empty())) // change to &&

I am not sure if that breaks logical correctness of your code but that was the cause of the segfault (it was coming from line 25)

The segfault happens on the line: if (buffer1.front() < buffer2.front())

A queue is typically just implemented as a wrapper around a deque or list you can find a more descriptive caution against calling front in their methods that you can in queue 's method:

Calling front on an empty container is undefined [1] [2]

If you're running under Debug in Visual Studio, when you get a segfault it will pop up this dialog, and you can hit "Retry" to debug with all state preserved:

在此处输入图片说明

You're problem is on this line though:

while ((!buffer1.empty()) || (!buffer2.empty()))

That means the while -loop is executed if either buffer1 or buffer2 is non-empty. You need to change that condition to:

while (!empty(buffer1) && !empty(buffer2))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM