-1

Im creating a code in C to remove all the negatives when given a double pointer array with some values, as well as a constant int size. My code behaves strange for the 3rd case, but works for the others. Can someone help point me in the right direction?

short remove_negatives(long** array, const int size){

    if (!*array  || !array || !**array){
        printf("Error(remove_negatives): invalid array\n");
        return -1;
    }
    if (size <= 0){
        printf("Error(remove_negatives): invalid size\n");
        return -1;
    }



    short count = 0;
    int i;

    for (i=0;i<size;i++){

        if (*(*array+i) < 0){

            *(*array + i) = *(*array + i + 1);
            count += 1;

        }
    }



    return count;
}

the output:

------------------------------
Start: Testing remove_negatives:

Case 1:
Before: {10,20,-10,30,40}
after: {10,20,30,30}
# removed items = 1

Case 2:
Before: {-10,20,-30,40,50,60,70}
after: {20,20,40,40,50}
# removed items = 2

Case 3:
Before: {10,-20,-30,-40,50}
after: {10,-30}
# removed items = 3

Case 4:
Before: {10,-20,-30,-40}
after: {10}
# removed items = 3

Case 5:
Before: {-10,-20,-30}
after: {}
# removed items = 3

Case 6:
Error(remove_negatives): invalid size
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
babybrick
  • 1
  • 1
  • Have you tried running your code line-by-line in a debugger while monitoring the values of all variables, in order to determine in which line your program stops behaving as intended? If you did not try this, then you may want to read this: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/12149471) You may also want to read this: [How to debug small programs?](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – Andreas Wenzel Jul 22 '22 at 21:12
  • Questions seeking debugging help should generally provide a [mre] of the problem, which includes a function `main` and all `#include` directives. This allows other people to easily test your program, by simply using copy&paste. – Andreas Wenzel Jul 22 '22 at 21:13
  • @babybrick Why does the first function parameter have the type long** array?! I do not see any sense in such a declaration. – Vlad from Moscow Jul 22 '22 at 21:21
  • @AndreasWenzel But, I will copy your comment for the future reference. – user14063792468 Jul 22 '22 at 21:27
  • 1
    Aside: this `if (!*array || !array || !**array)` should be `if (!array || !*array || !**array)` to avoid dereferening a NULL pointer (short-circuit evaluation). – Weather Vane Jul 22 '22 at 21:56
  • @user14063792468: I think it is important to inform posters when they are doing something wrong, so that they know how they can improve their post. Even if most posters do not follow the advice, it is worth it if at least some of them do. – Andreas Wenzel Jul 22 '22 at 21:57

1 Answers1

1

It is entirely unclear why the first function parameter has the type long ** array

short remove_negatives(long** array, const int size){

instead of long *array or long array[].

Also this if statement

if (!*array  || !array || !**array){

does not make a sense. Why may not for example **array be equal to 0? And at least the first expression in the if statement must be !array.

Nevertheless the function is incorrect at least due to this for loop

for (i=0;i<size;i++){

    if (*(*array+i) < 0){

        *(*array + i) = *(*array + i + 1);
        count += 1;

    }
}

If a negative element is encountered then it is replaced by the value of the next element.

*(*array + i) = *(*array + i + 1);

As a result if the next element is not negative then the two adjacent elements will have the same value. And this test case

Case 1:
Before: {10,20,-10,30,40}
after: {10,20,30,30}
# removed items = 1

demonstrates that.

Instead you need to move to the left all elements one position.

Moreover the for loop can invoke undefined behavior because the expression

*array + i + 1

can access memory beyond the array when i is equal to size - 1.

Below there is a demonstration program that shows how your function can be implemented.

#include <stdio.h>

size_t remove_negatives( int **a, size_t n )
{
    size_t k = 0;
    for ( int *p = *a, *q = *a; p != *a + n; ++p )
    {
        if ( *p < 0 )
        {
            ++k;
        }
        else
        {
            if ( p != q ) *q = *p;
            ++q;
        }
    }

    return k;
}

int main( void )
{
    while ( 1 )
    {
        size_t n;
        printf( "Enter the size of the array (0 - exit): " );

        if ( scanf( "%zu", &n ) != 1 || n == 0 ) break;

        int a[n];

        printf( "Enter %zu values: ", n );

        for ( size_t i = 0; i < n; i++ )
        {
            scanf( "%d", &a[i] );
        }

        printf( "Before: {" );
        for ( size_t i = 0; i < n; i++ )
        {
            printf( " %d", a[i] );
        }
        puts( " }" );

        int *p = a;
        size_t k = remove_negatives( &p, n );

        printf( "After: {" );
        for ( size_t i = 0; i < n - k; i++ )
        {
            printf( " %d", a[i] );
        }
        puts( " }" );

        printf( "# removed items = %zu\n ", k );
    }
}

For example if to enter data as in the test case #2 then the output of the array will look like

Before: { -10 20 -30 40 50 60 70 }
After: { 20 40 50 60 70 }
# removed items = 2
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • i see, thank you for your response. The array is set that way because my professor wanted us to work with double array pointers for this specific question to demonstrate our knowledge. How would I go about deleting an element while still preserving the values of the array ? – babybrick Jul 22 '22 at 22:43
  • @babybrick See my updated post. – Vlad from Moscow Jul 22 '22 at 23:05
  • @babybrick There were some typo but now I hope all is correct. Try the program. – Vlad from Moscow Jul 23 '22 at 08:23