Thread: I have segmentation fault with double pointers and pseudo generics using realloc

  1. #1
    Registered User
    Join Date
    May 2020
    Posts
    7

    Question I have segmentation fault with double pointers and pseudo generics using realloc

    Hello I have a question for you and I hope you can help me! I write here only the instructions for add 3 elements in a double pointer using item.h. So when I write "Item *a" is like void **a, right?
    Anyway the program works if I use malloc with dim=20 without realloc when I use output_array, but if I wanna start with dim=3 and after every insert_element I use realloc with dim+1 I get segmentation fault when I use output_array.
    With inselem_array(a,&dim); in my main I edit my "Item *a" using function? I thought this is like call by reference, so any change made to the reference pointer will effect the original pointer.
    When I have double pointer, is it like dynamic array with Item (alias void) pointers to other void pointers, right?
    I need your help! Can you help me please? Thanks in advance!


    I write 1 for start an array. I enter 1,2 and 3. After I write 3 for insert 4 in position a[1] for get 1,4,2,3 but I get segmentation fault and crash...


    main.c

    Code:
    #include "array.h"
    #include "item.h"
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int main(void) {
      int dim = 3;
      Item *a;
      int scelta = 0, b = 0;
      printf("1 - Insert elements in an array\n");
      printf("3 - Insert new element\n");
      printf("7 - Output array\n");
      printf("-1 - Exit");
      do {
        printf("\nWrite your choice\n");
        scanf("%d", &scelta);
        switch (scelta) {
        case 1:
          a = malloc(dim * sizeof(Item));
          input_array(a, dim);
          b = 1;
          break;
        case 3:
          inselem_array(a, &dim);
          break;
        case 7:
          output_array(a, dim);
          break;
        default:
          if (scelta != -1)
            printf("Wrong choice\n");
          break;
        }
      } while (scelta != -1);
      return 0;
    }




    array.h

    Code:
    #include "item.h"
    
    
    void input_array (Item *, int );
    void free_array();
    void inselem_array (Item *, int *);
    void output_array (Item [], int );

    array.c


    Code:
    #include "array.h"
    #include "item.h"
    #include "utils.h"
    #include <stdio.h>
    #include <stdlib.h>
    
    
    void input_array(Item *a, int n) {
      int i;
      for (i = 0; i < n; i++) {
        printf("Insert element number %d\n", i + 1);
        a[i] = inputItem();
      }
    }
    
    
    void free_array(Item *a) { free(a); }
    
    
    void output_array(Item *a, int n) {
      int i;
      for (i = 0; i < n; i++)
        outputItem(a[i]);
    }
    
    
    void inselem_array(Item *a, int *n) {
      int i, pos;
      Item item;
      printf("Insert new element\n");
      item = (inputItem());
      printf("Insert position for new element\n");
      scanf("%d", &pos);
      if (pos <= *n) {
        *n = *n + 1;
        a = realloc(a, *n * sizeof(Item));
    
    
        i = *n - 1;
        while (i > pos) {
          a[i] = a[i - 1];
          i--;
        }
        a[i] = item;
      } else
        printf("Wrong position\n");
    }
    item.h

    Code:
    typedef void *Item;
    
    
    Item inputItem();
    void outputItem(Item);
    int cmpItem(Item,Item);
    item-int.c

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include "item.h"
    
    
    Item inputItem(){
        int *p;
        p=malloc(sizeof(int));
        scanf("%d",p);
        return p;
    }
    
    
    void outputItem(Item item){
        int *p;
        p=item;
        printf("%d ",*p);
    }
    
    
    int cmpItem(Item item1,Item item2){
        int *p1,*p2;
        p1 = item1;
        p2 = item2;
        return *p1 - *p2;
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,064
    void inselem_array(Item *a, int *n)
    ...
    a = realloc(a, *n * sizeof(Item));

    Note that this will not change the value of 'a' as far as the caller of this function is concerned.
    They will still be using the old pointer.

    Which, if realloc moves the memory somewhere else, will be a big problem.

    Code:
    Item *inselem_array(Item *a, int *n) {
      int i, pos;
      Item item;
      printf("Insert new element\n");
      item = (inputItem());
      printf("Insert position for new element\n");
      scanf("%d", &pos);
      if (pos <= *n) {
        *n = *n + 1;
        a = realloc(a, *n * sizeof(Item));
     
     
        i = *n - 1;
        while (i > pos) {
          a[i] = a[i - 1];
          i--;
        }
        a[i] = item;
      } else
        printf("Wrong position\n");
    
      return a;
    }
    And main does
    a = inselem_array(a, &dim);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2020
    Posts
    7
    I thought with realloc is: old memory got thanks to malloc + new memory, so these two memories are together for get new memory for my dynamic array. I wanna start with 3 elements and after every inselem_array my dynamic array get a new slot for the new element. So how can I point for a new pointer?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,064
    *shrug*
    I just made the change I suggested, and voilą.

    Code:
    $ ./a.out 
    1 - Insert elements in an array
    3 - Insert new element
    7 - Output array
    -1 - Exit
    Write your choice
    1
    Insert element number 1
    22
    Insert element number 2
    33
    Insert element number 3
    44
    
    Write your choice
    3
    Insert new element
    42
    Insert position for new element
    1
    
    Write your choice
    7
    22 42 33 44 
    Write your choice
    3
    Insert new element
    99
    Insert position for new element
    4
    
    Write your choice
    7
    22 42 33 44 99 
    Write your choice
    -1
    > So how can I point for a new pointer?
    That's what the return a; is for at the end of the function (that I put in).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    May 2020
    Posts
    7
    Thank you for the fix! But can you tell me what is "*" front function? "*inselem_array"

  6. #6
    Registered User
    Join Date
    May 2020
    Posts
    7
    And another question, for example can I use inselem_array(&a,&dim); for avoid return?

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,064
    > But can you tell me what is "*" front function? "*inselem_array"
    It tells you that the function is returning a pointer.

    > for example can I use inselem_array(&a,&dim); for avoid return?
    You can, but you have to do something like
    Code:
    void inselem_array(Item **a, int *n) {
      int i, pos;
      Item item;
      printf("Insert new element\n");
      item = (inputItem());
      printf("Insert position for new element\n");
      scanf("%d", &pos);
      if (pos <= *n) {
        *n = *n + 1;
        *a = realloc(*a, *n * sizeof(Item));
      
      
        i = *n - 1;
        while (i > pos) {
          (*a)[i] = (*a)[i - 1];
          i--;
        }
        (*a)[i] = item;
      } else
        printf("Wrong position\n");
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    May 2020
    Posts
    7
    I see. Thank you very much!

  9. #9
    Registered User
    Join Date
    May 2020
    Posts
    7
    Sorry I have another question for my array.c so I ask here for don't open another thread. I added this function to my array.c to shuffle the array elements and it works with static Item *a; static int dim; in my array.c. Because I deleted Item *a from my main.c


    Code:
    void random_array() {
                                      int i , j;
                                      Item t;
                                      for (i = dim - 1;i > 0; i--)
                                      {
                                          j = rand() % (i + 1);
                                          t = a[i];
                                          a[i] = a[j];
                                          a[j] = t;
                                         //swap(a[i], a[j]);
                                      }
                               }
    So I tried with a function swap (a[i], a[j]) from the file utils.c but it doesn't work:

    Code:
    void swap (Item pa, Item pb) {
        Item t;
        t=pa;
        pa=pb;
        pb=t;
    
    }
    It works with these instructions:

    Code:
    void swap (Item *pa, Item *pb) 
    {
        Item t;
        t=*pa;
        *pa=*pb;
        *pb=t;
    }
    I know that with "typedef void *Item' Item t is like void *t and Item *a is like void **a, right?

    So with double pointers I have a dynamic array with many pointers thanks to a=malloc(numberelements*(sizeof(Item)); and with a[i]=malloc(sizeof(Item) every pointer points to a memory location with many bytes?

    Here a image.

    So for t I don't need malloc because with t = a[i] t points to memory location pointed from a[i], right?
    If yes, why do I have to use in my swap function t = *pa etc. instead of t = pa ? Thanks in advance!
    Attached Images Attached Images I have segmentation fault with double pointers and pseudo generics using realloc-doublepointers-jpg 
    Last edited by Cloudstrifeff7; 05-13-2020 at 02:58 AM.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,777
    If yes, why do I have to use in my swap function t = *pa etc.
    Because you don't just want to swap local copies of the Item objects, you want to swap the Item objects in the caller. Therefore the caller must pass pointers to Item.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    May 2020
    Posts
    7
    So with void swap (Item *pa, Item *pb) *pa and *pb are void **pa and **pb?

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,777
    Yes, and indeed you can dereference pointers to pointers to void, but you cannot validly dereference pointers to void.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 17
    Last Post: 01-15-2020, 07:36 AM
  2. Replies: 7
    Last Post: 10-03-2016, 08:04 AM
  3. Strcat with pointers and Segmentation Fault
    By thames in forum C Programming
    Replies: 6
    Last Post: 12-02-2012, 06:48 AM
  4. Realloc Segmentation Fault
    By workisnotfun in forum C Programming
    Replies: 14
    Last Post: 10-21-2012, 06:03 AM
  5. Replies: 8
    Last Post: 04-28-2008, 02:46 AM

Tags for this Thread