Shadow_visual
Shadow_visual

Reputation: 19

Operation on address of pointer: C

I am new to C, while finishing my homework I got stuck while on some pointer issue.
I the code below I'm trying to create a list, unsorted_deck is a string with white space and it has a size of 52.

char **order_deck(char *unsorted_deck, int size) {
    char *ptr;

    char *decks; //the list of String
    char **ptr_d = &decks;

    ptr = strtok(unsorted_deck, " ");

    printf("%i\n", size);

    for(int i = 0; i < size; i++) {
        *(ptr_d + i) = ptr;
        ptr = strtok(NULL, " ");
        printf("%i:==========%s========%li====\n",i, ptr, (long)(ptr_d+i));
    }

    return ptr_d;
}

For some reason unbeknownst to me, my code doesn't work at all.
It breaks in the for loop and sets the index i up to one thousand sometimes even more!

What follows is the output of my program :

1552:==========(null)========140735261699888====
1553:==========(null)========140735261699896====
1554:==========(null)========140735261699904====
1555:==========(null)========140735261699912====
1556:==========(null)========140735261699920====
1557:==========(null)========140735261699928====
1558:==========(null)========140735261699936====
1559:==========(null)========140735261699944====
1560:==========(null)========140735261699952====
1561:==========(null)========140735261699960====
1562:==========(null)========140735261699968====
1563:==========(null)========140735261699976====
1564:==========(null)========140735261699984====
1565:==========(null)========140735261699992====
1566:==========(null)========140735261700000====
1567:==========(null)========140735261700008====
1568:==========(null)========140735261700016====
1569:==========(null)========140735261700024====
1570:==========(null)========140735261700032====
1571:==========(null)========140735261700040====
1572:==========(null)========140735261700048====
1573:==========(null)========140735261700056====
1574:==========(null)========140735261700064====
1575:==========(null)========140735261700072====
1576:==========(null)========140735261700080====
1577:==========(null)========140735261700088====
Segmentation fault (core dumped)

Can anyone help me find out what's happened ? Thanks in advance.

Upvotes: 1

Views: 66

Answers (1)

bruno
bruno

Reputation: 32586

You have for sure 1 error, and 2 potential errors

But this absolutely doesn't work while it even break the for loop and make i achieves to one thousand even more! ... (core dumped)

as it is said in remark you do not initialize decks, this is the first error

and :

  • you do not stop the strtok when it returns NULL but depending on the value of size, are you sure size values the number of words in unsorted_deck ?

  • you do not copy (strdup) the result of strok, so you save pointers pointing into unsorted_deck, that suppose unsorted_deck is never modified and its life is enough long


If size values for sure the number of words in unsorted_deck

char **order_deck(char *unsorted_deck, int size) {
    char *ptr;
    char ** decks = malloc(size * sizeof(char *));

    if (desk == NULL)
      /* not enough memory */
      return NULL;

    ptr = strtok(unsorted_deck, " ");

    printf("%i\n", size);

    for(int i = 0; i < size; i++) {
      decks[i] = ptr; /* or  decks[i] = strdup(ptr); */
      printf("%i:%s\n",i, decks[i]);
      ptr = strtok(NULL, " ");
    }

    return decks;
}

If you do not know how many words there are in unsorted_deck realloc can be used to extend the resulting array.

you also need a way to indicate how many words you saved into the result. A first possibility is to change the role of size to be an output variable to be set by the number of words.

char **order_deck(char *unsorted_deck, int * size) {
    char *ptr;
    char ** decks = NULL;

    *size = 0;

    ptr = strtok(unsorted_deck, " ");

    while (ptr != NULL) {
      *size += 1;
      decks = realloc(decks, (*size) * sizeof(char *));
      if (deck == NULL) {
        /* not enough memory*/
        return NULL; /* because *size is not null the caller knows the problem */
      }

      decks[*size - 1] = ptr; /* or  decks[*size - 1] = strdup(ptr); */
      printf("%i:%s\n",*size - 1, decks[*size - 1]);
      ptr = strtok(NULL, " ");
    }

    return decks;
}

An other possibility is to ends the result with a NULL pointer.

char **order_deck(char *unsorted_deck) {
    char *ptr;
    char ** decks = NULL;
    int size = 0;

    ptr = strtok(unsorted_deck, " ");

    while (ptr != NULL) {
      size += 1;
      decks = realloc(decks, size * sizeof(char *));
      if (deck == NULL) {
        /* not enough memory*/
        return NULL;
      }

      decks[size - 1] = ptr; /* or  decks[size - 1] = strdup(ptr); */
      printf("%i:%s\n",size - 1, decks[size - 1]);
      ptr = strtok(NULL, " ");
    }

    /* add NULL ptr */
    decks = realloc(decks, (size + 1) * sizeof(char *));
    if (desk != NULL)
      decks[size] = NULL

    return decks;
}

Upvotes: 1

Related Questions