Thread: Delete an element in a dynamic array?

  1. #16
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    data[i] is a char *. t->cell[i] is a char**. These are, as you may have noticed, different. They need to be the same.

  2. #17
    C <3er
    Join Date
    Jul 2011
    Posts
    46
    Yeah thanks I noticed, I'm just getting so confused on getting this to worked so I'm messing things lol
    What I've got so far is:
    Code:
    void delete_row(table *t, int n){
        int i;
        --(t->rows);
        char ***data = malloc(t->rows * sizeof(char **));
        if(data == NULL){
            printf("\n\t\tERROR: Out of memory\n");
            printf("\n\t\tPress [Enter] to exit...\n");
            getchar();
            exit(EXIT_FAILURE);
        }
        for(i = 0; i < t-> rows; ++i){
            data[i] = malloc(t->cols * sizeof(char *));
            if(data[i] == NULL){
                printf("\n\t\tERROR: Out of memory\n");
                printf("\n\t\tPress [Enter] to exit...\n");
                getchar();
                exit(EXIT_FAILURE);
            }
        }
        for(i = 0; i < n; ++i)
            data[i] = t->cell[i];
        for(i = n; i < t->rows; ++i)
            data[i] = t->cell[i+1];
        free(t->cell[n]);
        free(t->cell);
    }
    But still doesn't work, I debugged it the function seems to exit correctly but then another function which uses table t is called and sigsev warning pops out, maybe it's the freeing of the t->cell which makes a null pointer appear somewhere?
    Thanks again!

  3. #18
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    In the sense that once you free(t->cell), your table ceases to exist, then that could be a problem. Perhaps you meant to replace t->cell with data and then free the old t->cell.

  4. #19
    C <3er
    Join Date
    Jul 2011
    Posts
    46
    Yeah I that's what I meant a few posts ago that I don't want to create a new table I need to modify this one, thus freeing the table seemed to me a bit weird
    Perhaps you meant to replace t->cell with data and then free the old t->cell.
    How should I go about that then? I mean I tried shifting all the rows after the row being deleted one position less and freeing just the last row which made sense to me but I might be still trying in the wrong a direction and can't get what you are trying to tell me? :S

  5. #20
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    "t->cell = " is generally the way you replace things.

  6. #21
    C <3er
    Join Date
    Jul 2011
    Posts
    46
    Yeah I know that but do you mean doing t->cell = data just before freeing t->cell or how can I delete the "old" t->cell? I can't still get how can I redefine let's say "A" and then delete old "A"? I mean if I try and delete "A" it doesn't exist anymore right? (neither old nor new)
    Sorry if I make too much questions but I don't get how to solve this, it puzzles me :S
    Thanks again!

  7. #22
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You have to put the old one somewhere first in order to free it. "about_to_be_deleted" is a good name, I suppose.

  8. #23
    C <3er
    Join Date
    Jul 2011
    Posts
    46
    Ok so I think I got now in my head what you are saying, I should free data in my code not t->cell, I use data to modify the table then free data right? Well I will try to code it that way, seems logical (although I might be wrong again xD)

  9. #24
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    That sounds like a recipe for disaster.

  10. #25
    C <3er
    Join Date
    Jul 2011
    Posts
    46
    Mmmmm nice...Why disaster may I ask? then I don't know what else to do thanks for the help!

  11. #26
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Well... you could just move the data over and leave an empty row there.

    For all you know the user's next step will be to add a row...

  12. #27
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by beta3designs View Post
    Mmmmm nice...Why disaster may I ask? then I don't know what else to do thanks for the help!
    You can't delete data that you are expecting to actually continue to use. You can assign the pointer, that's fine; now you have two pointers pointing to the same place, so you can't free either of them (because that will release the memory pointed to). You need to free the stuff you're not going to keep using.

  13. #28
    C <3er
    Join Date
    Jul 2011
    Posts
    46
    Ok, but I was just trying to follow quzah's example:
    5. Free the second row. (free( olddata[ 1 ])
    6. Free our old row pointers. ( free( olddata ) )
    I know I have two pointers pointing at the same place but as I was following quzah's example I thought I needed to free the old row pointers but now you say
    you can't free either of them
    So I don't know, do you mean step 6 is wrong and I should only do step 5? delete the row which won't be used?
    Thanks again!

  14. #29
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    That is exactly what you want to do. However, you need to give the new memory to the person who is calling the function. You've created this new table data, which nobody outside this function is ever going to see. You need to put that data in your table, which is why you need to do t->cell = data. Then you must free your old row pointers. t->cell isn't your old data any longer, so don't free it. data has never been your old data, so you can't free that either. You need to free the old data. As you say, when you put the new pointer in your table, that replaces the old pointer, so you need to keep hold of it in order to free it in step 6.

    Code:
    void *data_that_is_to_be_deleted = t->cell;
    t->cell = data; /* move the new data into the table so that your table will continue to exist */
    free(data_that_is_to_be_deleted);
    EDIT: And for that matter you don't even need the temp, as long as you bother to actually return the data:
    Code:
    free(t->cell);
    t->cell = data;
    It looks "wrong" because at first glance you're using a pointer right after you free it, but in actuality that isn't true.
    Last edited by tabstop; 08-19-2011 at 02:44 PM.

  15. #30
    C <3er
    Join Date
    Jul 2011
    Posts
    46
    Ok I understand that isn't actually wrong and now I think I understand the idea but when you said "data" did you mean all the table entries without the deleted row?
    Well I coded this:
    Code:
    void delete_row(table *t, int n){
        int i, j;
        --(t->rows);
        char ***data = malloc(t->rows * sizeof(char **));
        if(data == NULL){
            printf("\n\t\tERROR: Out of memory\n");
            printf("\n\t\tPress [Enter] to exit...\n");
            getchar();
            exit(EXIT_FAILURE);
        }
        for(i = 0; i < t-> rows; ++i){
            data[i] = (char **)malloc(t->cols * sizeof(char *));
            if(data[i] == NULL){
                printf("\n\t\tERROR: Out of memory\n");
                printf("\n\t\tPress [Enter] to exit...\n");
                getchar();
                exit(EXIT_FAILURE);
            }
            for (j = 0; j < t->cols; j++){
                data[i][j] = (char *)malloc(NAME_MAX_LEN * sizeof(char));
                if(data[i][j] == NULL){
                    printf("\n\t\tERROR: Out of memory\n");
                    printf("\n\t\tPress [Enter] to exit...\n");
                    getchar();
                    exit(EXIT_FAILURE);
                }
            }
        }
        for(i = 0; i < n; ++i)
            data[i] = t->cell[i];
        for(i = n; i < t->rows; ++i)
            data[i] = t->cell[i+1];
        free(t->cell[n]);
        free(t->cell);
        t->cell = data;
    }
    It works just perfectly buut I might have missunderstood something so just in case, if you can check it out I'd be glad to hear your opinion.
    Thanks again!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. dynamic array and losing data of the first element
    By fx69 in forum C++ Programming
    Replies: 9
    Last Post: 02-25-2010, 05:15 AM
  2. how delete 1th element of a sorted array
    By vicky_4040 in forum C Programming
    Replies: 4
    Last Post: 10-11-2009, 06:12 AM
  3. delete same array element in C
    By tasosa in forum C Programming
    Replies: 12
    Last Post: 04-09-2009, 09:36 AM
  4. Delete Samllest Array Element
    By ptysell in forum C Programming
    Replies: 5
    Last Post: 11-22-2004, 07:27 PM
  5. Cannot delete last element in array
    By Simon in forum C Programming
    Replies: 10
    Last Post: 09-12-2002, 08:29 PM

Tags for this Thread