+5  A: 

Apparently you're confusing an array of alumn structs with an array of pointers to alumm struct.

The Bubble logic expexts the array of pointers, whereby the main function seems to call it with an array of structs.

Because of the size of the alumn struct, it is probably more efficient to perform the bubble sort on pointers, since each swap will require much less moving around of data (3 copies of one pointer a few bytes each, vs. 3 copies of alumn struct, 200+ bytes each!).

I suggest you modify the logic (not shown in snippet of question) of the main() function to introduce such an array of pointers to the actual alumn structs. (Of course this array of pointers won't spare you from also allocating the structs themselves, en block (in an array of structs) or individually.


Upon your insistence I'm hinting here how main could look like to produce an array of pointer usable by bubble (bubble stays unchanged).
BTW, I declare alumns as alumn *alumns[] which shows the intent use more readily. this is the same thing as alumn **alumns.

int main(int argc, char **argv)
{
    alumn *alumns[];   // changed to array of pointers [to alumn structs] 
                       // was pointer to alumn struct, likely to be used as an array thereof

    int MaxNbOfAlumns = some_limit;
    alumns = malloc(sizeof(*alumn) * MaxNbOfAlumns);

    // Load the alumn records (from file or whereever)
    // pseudo code:
    // int i_alumns = 0;  // points to the next free slot in alumns array
    // for each record (in file or whereever...)
    //     alumms[i_alums] = malloc(sizeof(struct alumn));
    //     strcpy(alumms[i_alums]->lastname,  whatever_data);
    //     strcpy(alumms[i_alums]->name,  whatever_otherdata);
    //     alumms[i_alums]->par = some_int_data;
    //     alumms[i_alums]->nota = some_other_int_data;
    //     i_alums++;

... here goes some other code ...

  bubble(alumns, totalAlumns);   // alumns now being an array can be passed as is.

  return 0;
}

Alternatively if you wish to keep the original alumns variable as previously, all that may be needed is something like that, just before the call to bubble()

  int i;
  alumn *ap_alumns[];   // new variable
  ap_alumns = malloc(sizeof(*alumn) * totalAlumns);
  for (i = 0; i < totalAlumns; i++)
      ap_alums[i] = &alumns[i];
  bubble(ap_alumns, totalAlumns);  

One thing that should be stressed is that regardless of its genesis, the array passed to bubble() gets sorted ok, but to use it you need to dereference the individual pointers.
Whereby with the old array you intended to use as in say alumns[123].lastname, you'll now need alumns[123]->lastname (or ap_alumns[123]->lastname if you use the second version).

mjv
Can you help to do the swap implementation with pointers?
dilog
I can, but won't. For one it is readily implemented as such (in bubble() function) and second, this seriously looks like homework, hence worthy of hints but _you_ will be the better for figuring things for yourself. I think you'll agree ;-)
mjv
ok i'm understand. Look only i need a little help, the only thing that is failing to me is the swap method, i want to change the pointers, so *arr points to alumn but the thing tha i can't figure its how in terms of arr reference a member of the alumn array. Any help?
dilog
@dilog: see edit. With two versions on how to create the array of pointers needed.
mjv
A: 

Your code does not work because you have an array of structs instead of an array of pointers.

When you try to swap two structs, the = operator does not know what to do. You have to copy the fields of the struct one by one for that to work.

If you had an array of pointers to instances of the alumn struct instead. THen the code would work, since you are assigning pointers. A pointer is basically a number and = knows how to copy a number.

kkrizka
buddy i'm swapping pointers not the structs himself. The parameters of the function contain a pointer to the array structs.
dilog
alumn **arr means that arr points to a array of structs not array of pointers to structs, as was already pointed out above.
kkrizka
A: 

Your code is written as if you have an array of pointers, but have left out an important part of your code (i.e., ... here goes some other code ...) so we can't see how you've set up the thing to be sorted. If you have an array of pointers, this line of code:

if ((*arr)[i].nota > (*arr)[j].nota) {

should be:

if (arr[i]->nota > arr[j]->nota) {

The reason is, (*arr) gets the first pointer in the list, then (*arr)[i] gets the i'th item in memory after that pointer (meaningless since each pointer should point to one item). The 2nd syntax goes to the i'th pointer in the pointer array, and dereferences it to get that value.

Maybe this illustration will help:

arr points to an array of two pointers, each pointing to a struct.
(*arr)[1].nota refers to an item in ??????.
arr[1]->nota refers to an item in struct 2.

       +---+                   +----------+
arr -> | * | ----------------> | struct 1 |
       +---+    +----------+   +----------+
       | * | -> | struct 2 |   :  ??????  :
       +---+    +----------+   +..........+
Mark Tolonen