1

Objective: I'm working with pointers and I'm running into quite a few problems. Last week assignment was to write an insertion sort function to sort a ragged array in descending order. This week my professor wants me to change out all the indices and use only pointers.

void insert(int **table, int row)
{

    //  Local Declaration
    int **ptr = table;
    int **walkPlus, *walk, temp;

    //  Statement
    for(ptr = (table + 1); *ptr != NULL; ptr++)
    {
        temp = **ptr;
        walk = *(ptr - 1);
        while(*walk >= diff && temp > *walk)
        {
            walkPlus = ptr;
            **walkPlus = *walk;
            *walk--;
        }
        **walkPlus = temp;
        printf("\n");
    }
    return;

}

I feel that *walk--; is the cause to my problem. When I use printf statement to check it's value, but I'm getting a weird address. I know pointers are really important and I want to make sure that I understand the concept, so any help would be appreciated. Thank you.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#ifdef _MSC_VER
#include <crtdbg.h>  // needed to check for memory leaks (Windows only!)
#endif

#define MEM_ERROR printf("Not enough memory\n")

int** getRow(int *row);
void valiRow(int *row);
void getSize(int **table, int row);
void  valiSize(int *size);
void fillTable(int **table, int row);
void bubble(int **table, int row);
void insert(int **table, int row);
void freeAlo(int **table);

int main (void)
{
//  Local Declaration
int **table;
int row, i;
char answer;
int **pTable;
FILE* fpOutPut;

//  Statement

fpOutPut = fopen("Output.txt", "w");
if(fpOutPut == NULL)
{
    printf("Error, writing failed.\n");
    exit(103);
}

do
{
    table = getRow(&row);
    getSize(table, row);
    fillTable(table, row);
    bubble(table, row);
    insert(table, row);
    freeAlo(table);

    printf("\nDo you want to create a new ragged table? ");
    printf("[y] to continue: ");
    scanf(" %c", &answer);
    printf("\n");

}
while(toupper(answer) == 'Y');
fclose(fpOutPut);

#ifdef _MSC_VER
printf( _CrtDumpMemoryLeaks() ? "Memory Leak\n" : "No Memory Leak\n");
#endif
return 0;

}// main

/* getRow */
int** getRow(int *row)
{
//  Local Declaration
int **table;

//  Statement
printf("Please enter the number of rows (1-10): ");
scanf("%d", &*row);

valiRow(&*row);

table =(int**)calloc(*row + 1, sizeof(int));
if(table == NULL)
    MEM_ERROR, exit(100);

return table;
}

/* valiRow */
void valiRow(int *row)
{
//  Statement
while(*row > 10 || *row < 1)
{
    while(getchar() != '\n')
    ;
    printf("Please enter a number between (1-10): ");
    scanf("%d", &*row);
}

return;
}
/* getSize */
void getSize(int **table, int row)
{
//  Local Declaration
int size;
int **ptr = table;
int **pLast = table + row;

//  Statement
ptr = table;
for( ; ptr < pLast; ptr++)
{
    printf("Please enter a size (1-15): ");
    scanf("%d", &size);

    valiSize(&size);

    *ptr = (int*)calloc(size + 1, sizeof(int));
    **ptr = size;
}

if(table == NULL)
    MEM_ERROR, exit(101);

return;
}

/* valiSize */
void valiSize(int *size)
{
//  Statement
while(*size > 15 || *size < 1)
{
    while(getchar() != '\n')
    ;
    printf("Please enter a valid size (1-15): ");
    scanf("%d", &*size);
}

return;
}

/* fillTable */
void fillTable(int **table, int row)
{
//  Local Declaration
int random;
int **ptr = table;
int *pCurr, *pWalk;

//  Statement
srand(time(NULL));
for(pCurr = *ptr ; *ptr != NULL; ptr++)
{
    for(pWalk = (pCurr + 1); *pWalk < *pCurr; pWalk++)
    {
        random = -99 + rand() % 199;
        *pWalk = random;
    }
    pCurr = *(ptr + 1);
}

return;
}

/* bubble */
void bubble(int **table, int row)
{
//  Local Declaration
int **ptr;
int *pWalk;
int temp, target;

//  Statment
for(ptr = table; *ptr != NULL; ptr++)
{
    for(target = **ptr; target > 0; target--)
    {
        for(pWalk = *ptr + target; pWalk != *ptr + 1; pWalk--)
        {
            if(*pWalk > *(pWalk - 1))
            {
                temp = *pWalk;
                *pWalk = *(pWalk - 1);
                *(pWalk - 1) = temp;
            }
        }
    }
}

return;
}

/* insert */
void insert(int **table, int row)
{
//  Local Declaration
int **ptr = table;
int temp, *walk, **walkPlus;

//  Statement
for(ptr = (table + 1); *ptr != NULL; ptr++)
{
    temp = **ptr;
    walk = *(ptr - 1);
    while(*walk >= 0 && temp > *walk)
    {
        walkPlus = ptr;
        **walkPlus = *walk;
        *walk--;
    }
    **walkPlus = temp;
}
return;
}

/* freeAlo */
void freeAlo(int **table)
{
//  Local Declaration
int ** ptr;

//  Statement
for(ptr = table; *ptr != NULL; ptr++)
{
    free(*ptr);
}
free(ptr);

return;
}
Nathan
  • 483
  • 4
  • 7
  • 19
  • 1
    What's the actual problem> – Tony The Lion Feb 12 '13 at 08:03
  • You are trying to sort an array of integers so you should be working with `int*`'s not `int**`'s – Bernd Elkemann Feb 12 '13 at 08:09
  • @eznme: Presumably by "ragged array", the OP is working with a multi-dimensional array, and wants to sort it by the first column, or something like that. – Oliver Charlesworth Feb 12 '13 at 08:10
  • @TonyTheLion: My array isn't sorting in descending order. After running thorough the loop, the first column of values stayed the same. – Nathan Feb 12 '13 at 08:15
  • Is this a ragged array (an array of pointers to arrays), and if so, how many *columns* does it have (or do you even care and just want to sort by the first one)? – WhozCraig Feb 12 '13 at 08:37
  • He calls it "ragged array" but that term does not mean anything, as opposed to https://en.wikipedia.org/wiki/Iliffe_vector . Also the question remains why Iliffe at all?: If one column is to be sorted by another column then both should have the same length and would better be passed as two separate arguments – Bernd Elkemann Feb 12 '13 at 08:41
  • @WhozCraig: yes it's an array of pointers that points to another array of integers that has been allocated in previous functions. I'm trying to sort the array of pointers, but at the same time making sure it still points to the corresponding array of integers to begin with. Example before sort: 2: 10 9 8 7 1: 4 5 6 3: 2 1 0 After sort: 3: 2 1 0 2: 10 9 8 7 1: 4 5 6 – Nathan Feb 12 '13 at 08:50
  • 1
    @eznme: "Ragged/jagged array" is a well-understood term. And it's perfectly sensible to want to sort the rows (which happen to be of unequal length) by the values in the first column. – Oliver Charlesworth Feb 12 '13 at 08:50
  • @OliCharlesworth I concur, just looking for a solid clarification. – WhozCraig Feb 12 '13 at 08:52
  • @Nathan we can only help if you show us the rest of your code – Bernd Elkemann Feb 12 '13 at 09:24
  • @eznme: okay, I've uploaded my whole code. The insert function is the one I'm having trouble with. – Nathan Feb 12 '13 at 10:37

2 Answers2

0

Post fix operator -- has higher precedence than unary operator *. You need to take care of that. Have you overlooked it? Please look into the precedence table in the following link

Shortcut to remember the Order of Evaluation and Precedence of Operators in C

Community
  • 1
  • 1
Kranthi Kumar
  • 1,184
  • 3
  • 13
  • 26
0

Thanks for posting the rest of the code

I have taken a look, first i would recommend you activate all warnings your compiler can show -Wall etc.

Now, the actual thoughts:

In your middle nested for-loop you check target = **ptr; target > 0. This means that your code will only work as long as there are no 0's in your arrays! Instead of trying to 0-terminate you could instead pass the number of entries as an argument (in addition to the pointer to the array).

About the triple-nested for-loop etc: The code suggests you just want to sort the rows independently (ie not one row by the order given in another), so the first thing you should do is make a function which sorts a single array, if you have that then you can call it on the individual arrays.

EDIT: to your comment, ok make sure you remove main()'s call to bubble() otherwise you cannot really tell which of the sort-functions (bubble vs insert) did what.

Now with warnings enabled (-Wall etc., depending on compiler), you would see this:

a.c: In function 'fillTable':
a.c:138:33: error: unused parameter 'row' [-Werror=unused-parameter]
a.c: In function 'insert':
a.c:175:4: error: value computed is not used [-Werror=unused-value]
a.c:160:30: error: unused parameter 'row' [-Werror=unused-parameter]

For example the one in line 175 tells what Kranthi Kumar mentioned in his answer. To be clear: *walk-- does not do anything, try --*walk. The unused parameter warnings show that maybe something was forgotten. Also, when you fixed these, there may appear additional errors that also need fixing.

EDIT 2: what i mentioned for the other sort-function is true for insert() too: you are using while(*walk >= 0..., which means that your function will only work on arrays that:

  • contain no negative values
  • have a negative value at index (-1) this is broken!

Good luck!

Bernd Elkemann
  • 23,242
  • 4
  • 37
  • 66
  • Thanks for the quick reply, but the function you just helped me with was for bubble sorting. Sorry, I usually write the function denfinition after my program is finished, but thanks for addressing that. The function I'm having trouble with is right under /* insert*/. I appreciate your time and effort in helping me! – Nathan Feb 12 '13 at 11:58