Как удалить конкретную строку из массива строк в C? - PullRequest
0 голосов
/ 14 февраля 2019

Мне нужна функция, которая получает массив указателей на строки и его размер.Затем он должен искать те строки, которые встречаются в массиве более одного раза - тогда я должен удалить их и перераспределить массив.Функция должна вернуть новый размер массива.Я пытаюсь решить эту проблему, и не уверен, что случилось.

Я хочу переместить каждую строку, которую я хочу удалить, в конец массива, а затем удалить его, но не уверен, когдадолжно произойти "realloc".

#include<stdio.h>
#include<stdlib.h>

int DeleteString(char** tab, int n){
    char* check=malloc(sizeof(char)*100);
    int deleted;
    int i,j,g,h;

    for(i=0;i<n;i++){
        strcpy(check, tab[i]);
        for(j=0;j<n;j++){
            if(strcmp(check, tab[j]) == 0){     
                deleted++;
                char* temp = malloc(sizeof(char)*100);
                for(h=j;h<n-1;h++){
                    strcpy(temp, tab[h+1]);
                    strcpy(tab[h+1], check);
                    strcpy(tab[h], temp);       
                }
            }

            if(deleted>0){
                realloc(tab, sizeof(char*)*(n-deleted));
            }
        }
    }
    return n-deleted;
}

На данный момент есть ошибка "Ошибка сегментации"

Ответы [ 3 ]

0 голосов
/ 14 февраля 2019

Ой, ваш код содержит множество проблем, потому что вы не соблюдали некоторые основные правила языка Си:

  • каждая нестатическая переменная должна быть инициализирована (как насчет deleted?)
  • любой объект, который был заблокирован, должен быть освобожден (как насчет check и temp.)
  • никогда не изменять то, что было передано в качестве входного параметра функции, или не ожидать, что изменениебыть видимым при возврате (здесь необходимо учитывать tab из-за следующей строки).
  • всегда присваивает результат realloc, поскольку он может отличаться от входного указателя (realloc(tab, sizeof(char*)*(n-deleted));).

Первый, вероятно, является причиной ошибки сегментации, так как deleted унифицирован, его значение просто не определено.Но все проблемы должны быть исправлены.

0 голосов
/ 15 февраля 2019

Прежде всего, не забудьте инициализировать переменные, такие как deleted, как было сказано в других ответах.

Далее вы должны освободить память (так как вы удаляете элементы) иВы только звоните malloc(3)).Это кажется немного противоречащим здравому смыслу, не так ли?

В-третьих, вы делаете много строкового копирования в циклах, в то время как это должно быть более эффективным, просто перемещая указатели вверх, так что вы не делаетенужно перераспределить строковые элементы и скопировать содержимое ячейки (кстати, вы уверены, что эти строки будут переданы в функцию как malloc() d строк? Я предполагаю, что, как и вы)

В-четвертых,рассмотрим сначала сортировку массива, чтобы все похожие строки были соседними в массиве.Это имеет стоимость O(n*log(n)), которая при добавлении к следующей строке удаления, если она равна (при стоимости O(n)), составляет общую стоимость O(n*(log(n)+1)) или O(n*log(n)), а не O(n^2), которая является вашей фактической стоимостью)

После сортировки, только удаленные строки должны быть free(3) d, указатели перемещаются обратно в начало массива, когда появляются дыры, и, наконец, (когда все закончено), вы можете просто realloc(3) массив указателей (толькоодин раз, не при каждом прохождении цикла)

Пересмотр примера выходит за рамки этого ответа, так как на самом деле это выглядит как школьное упражнение.Простите за это.Я уверен, что другие подсказки помогут вам повторить упражнение с большим успехом.

И подумайте: думать перед тем, как писать, - это то, как человек преуспевает в этой работе.

0 голосов
/ 14 февраля 2019

Причиной НЕУДАЧИ СЕГМЕНТАЦИИ является вкладка [0], в которой хранится адрес переменной, в которой хранится фактическая строка.Здесь вкладка [i] находится в цикле for, следовательно, когда она пытается получить ошибку памяти самой вкладки [1].

for(i=0;i<n;i++){
    strcpy(check, tab[i]);...}

FOR EXAMPLE:

 char *foo = "something";
 char **ptr2;
 ptr2 = &foo;
 printf("check = %s", *ptr2); 
 for(int i=0;i<9;i++){  
   printf(" check = %c",  ptr2[i]);
 }

Output

check = something check = 4check = �check = pcheck =

На самом деле это ошибка.

...