Suppose I have a two-dimensional array consisting of 3 lines. I need to delete the 2nd line for example. How to do it?

char* GetLine(){ char* text = NULL; char ch; int counter; for(counter = 1 ;; counter++){ ch = getchar(); text = (char*)realloc(text,counter*sizeof(char)); if(ch != '\n'){ *(text+counter-1) = ch; } else{ *(text+counter-1) = '\0'; break; } } return text; } int main(void) { // Disable stdout buffering setvbuf(stdout, NULL, _IONBF, 0); char **lines = NULL; int i; lines = (char**)malloc(sizeof(char*)*3); for(i = 0; i < 3;i++){ *(lines+i) = GetLine(); } for(i = 0; i < 3; i++){ puts(*(lines+i)); } return 0; } 

    2 answers 2

    As in any array of any elements

    Suppose we have T array[N] , and we need to delete the element number M :

     memmove(array+M, // адрес M-го элемента array+M+1, // адрес M+1-го элемента sizeof(T)*(NM-1)); // количество байт 

    Before that, you must perform all the necessary actions to clean up the M th element — for example, if it is a pointer to a dynamically executed memory — to free it.
    After that you have to remember that there is an N-1 element in the array and work accordingly. If you really want to - you can call realloc .

    Your two-dimensional array is essentially a one-dimensional array of pointers to dynamically allocated memory.

    And, by the way, for this

     for(counter = 1 ;; counter++){ ch = getchar(); text = (char*)realloc(text,counter*sizeof(char)); 

    I would lower the estimate. It’s not a job for each character to cause realloc - it’s not a saving, but a waste ...

    • Thank you, about the latter, I understand you advise you to pre-allocate the n-th amount of memory, and then adjust if there is a shortage / excess memory? - ReCursia
    • Yes, depending on the task. If this is a human input, then for starters, 100 characters should suffice :) And then increase it by a certain amount of times. And only then, when introduced - and if the excess of the allocated memory over the actual required is critical for the program and the system - then use realloc already. - Harry
    • @harry, this is not only a brake, but also a frank bug in the code - 0andriy
    • @ 0andriy What exactly? Offhand, I only see that ch must be int 'th, and that there is no text checking after realloc .. - Harry

    One of the options for working with an array of pointers.

     typedef struct s_line_ s_line struct s_line_ { char ** str; int number; int amount; }; #define AMOUNT_LINE 10 int alloc_line(s_line *line) { int t; char ** str; if(line->amount == 0){ t = AMOUNT_LINE; } else{ t = (line->amount << 1); } str = (char **)malloc((sizeof(char*)*t)); memset(str,0,t); if(line->str != NULL){ memmove(str,line->str,line->amount); free(line->str); } line-str = str; return 0; } int add_str(s_line * line,char * str) { if(line->amount == line->number){ alloc_line(line); } line->str[line->number] = str; line->number ++; return 0; } int remove_str(s_line * line,int number) { char * str; char ** dest,src; if(number >= line->number){ return -1; } str = line->str[number]; free(str); dest = line->str; src = line->str; dest += number; src += (number+1); memmove(dest,src,((line->number - 1) - number)); line->number--; return 0; } int main(int argc,char * argv[]) { s_line line = {0}; char * str; for(i = 0; i < 5;i++){ str = GetLine(); add_line(&line,str); } for(i = 0; i < line.number; i++){ puts(lines.str[i]); } remove_str(&line,2); return 0; }