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.
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.
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:
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?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); }
Thanks again!
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.
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
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? :SPerhaps you meant to replace t->cell with data and then free the old t->cell.
"t->cell = " is generally the way you replace things.
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!
You have to put the old one somewhere first in order to free it. "about_to_be_deleted" is a good name, I suppose.
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)
Mmmmm nice...Why disaster may I ask? then I don't know what else to do thanks for the help!
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...
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.
Ok, but I was just trying to follow quzah's example:
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 say5. Free the second row. (free( olddata[ 1 ])
6. Free our old row pointers. ( free( olddata ) )
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?you can't free either of them
Thanks again!
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.
EDIT: And for that matter you don't even need the temp, as long as you bother to actually return the data: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);
It looks "wrong" because at first glance you're using a pointer right after you free it, but in actuality that isn't true.Code:free(t->cell); t->cell = data;
Last edited by tabstop; 08-19-2011 at 02:44 PM.
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:
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.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; }
Thanks again!