4

I'm writing a program that has a user input integers into an array, calls a function that removes duplicates from that array, and then prints out the modified array. When I run it, it lets me input values into the array, but then gives me a "Segmentation fault" error message when I'm done inputing values. What am I doing wrong?

Here is my code:

#include <iostream>

using namespace std;

void rmDup(int array[], int& size)
{
        for (int i = 0; i < size; i++)
        {
            for (int j = i + 1; j < size; j++)
            {
                if (array[i] == array[j])
                {
                    array[i - 1 ] = array[i];
                    size--;
                }
            }
        }
}
int main()
{
    const int CAPACITY = 100;
    int values[CAPACITY], currentSize = 0, input;

    cout << "Please enter a series of up to 100 integers. Press 'q' to quit. ";

    while (cin >> input)
    {
       if (currentSize < CAPACITY)   
       {
           values[currentSize] = input;
           currentSize++;
       }
    }

    rmDup(values, currentSize);

    for (int k = 0; k < currentSize; k++)
    {
            cout << values[k];
    }

    return 0;
}

Thank you.

4
  • For c++ consider using std::vector<int> instead of int array[] Commented Dec 10, 2013 at 18:10
  • 2
    Why not use the Standard Library? using namespace std; sort(begin(values), end(values)); size = unique(begin(values), end(values)) - begin(values); Commented Dec 10, 2013 at 18:20
  • I don't know those commands (sort, end, unique), but I'll definitely become familiar with them. Commented Dec 10, 2013 at 23:07
  • consider the boundary line case ( general technic when dealing with arrays ). When i = size - 1 , then j will become size . It mneans array[j] will be array[size] . That means crash:) Commented Oct 24, 2014 at 4:09

4 Answers 4

4
for (int i = 0; i < size; i++)
{
    for (int j = i + 1; j < size; j++)
    {
        if (array[i] == array[j])
        {
            array[i - 1 ] = array[i]; /* WRONG! array[-1] = something */
            size--;
        }
    }
}

If array[0] and array[1] are equal, array[0-1] = array[0], meaning that array[-1] = array[0]. You are not supposed to access array[-1].

Sign up to request clarification or add additional context in comments.

1 Comment

These comments got me on the right track I think. I'm amazed at how quickly this community responds. Thank you.
1

I wouldn't make it even possible to create duplicates:

int main()
{
    const int CAPACITY = 100;

    cout << "Please enter a series of up to 100 integers. Press 'q' to quit. ";

    std::set<int> myInts;
    int input;
    while (std::cin >> input && input != 'q' && myInts.size() <= CAPACITY) //note: 113 stops the loop, too!
       myInts.insert(input);

    std::cout << "Count: " << myInts.size();
}

And do yourself a favour and don't use raw arrays. Check out the STL.

2 Comments

I wasn't initially aware that I could accidentally create duplicate arrays. Thanks for the tip.
You create not duplicate arrays but duplicate values in an array. std::set "prevents" that.
0
#include <algorithm>
#include <iostream>
#include <iterator>

using namespace std;
int main()
{
    vector<int> vec = {1,1,2,3,3,4,4,5,6,6};
    auto it = vec.begin();

    while(it != vec.end())
    {
        it = adjacent_find(vec.begin(),vec.end());
        if(it != vec.end())
            vec.erase(it);
            continue;
    }

    for_each(vec.begin(),vec.end(),[](const int elem){cout << elem;});
    return 0;
}

This code compiles with C++11.

5 Comments

I think it's faster with vec.erase(unique(begin(vec), end(vec)), end(vec));, and also that gets rid of the loop.
for_each(vec.begin(),vec.end(),[](const int elem){cout << elem;}); Alternatively with a range-based for: for(auto const& e : vec) std::cout<<e<<", ";
When you use vec.erase(it), you invalidate it. I'm not sure if it's safe to compare an invalid iterator against the end iterator (in the next loop iteration).
Using std::vector for erasing is expensive bacause all subsequent elements must be re-alocated after each erase() call. std::list with constant erase time should be prefered in this case.
I haven't begun using vectors yet, but will look into them. Thank you for the help.
0
#include<iostream>
#include<stdio.h>
using namespace std;

int arr[10];
int n;

void RemoveDuplicates(int arr[]);
void Print(int arr[]);


 int main()
{

cout<<"enter size of an array"<<endl;
cin>>n;
 cout<<"enter array elements:-"<<endl;
for(int i=0;i<n ;i++)
{
    cin>>arr[i];
}
RemoveDuplicates(arr);
Print(arr);
}

 void RemoveDuplicates(int arr[])
{
   for(int i=0;i<n;i++)
{
    for(int j=i+1;j<n;)
    {
        if(arr[i]==arr[j])
        {
            for(int k=j;k<n;k++)
            {
                arr[k]=arr[k+1];

            }
            n--;
        }
        else
            j++;
    }
}
}

void Print(int arr[])
{
   for(int i=0;i<n;i++)
   {
      cout<<arr[i]<<"  ";
    }
 }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.