поиск дубликатов из массива указателей - PullRequest
1 голос
/ 21 июня 2011

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

, когда я обнаружу дубликаты, я просто поместил эти строки в файл с именем output.txt.

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

      main()
      {
           char *a[20];
           DIR             *dip;
           int i = 0;
           dip = opendir("src/my_folder");
           char *condition_var; 


           while ((dit = readdir(dip)) != NULL)               
           {
           condition_var = dit->name;      

            a[i] = condition_var
                            i++;
            }
            findduplicates(a,i);
       }

      char *findduplicates(char *arr[3],int count)
      {
      int i = 0;
      int j = 0;
      int val = 0;
      FILE *output = fopen("output.txt","w");
      for(i = 0;i<count;i++)
      { 
               j = i+1;
       for(;j<count;j++)
       {
             if(strcmp(arr[i],arr[j])==0)
             {
           printf("The index of a duplicate elemnt is %d\n",j);
           arr[j] = " ";

             }
        }

      }
int k = 0;
while(k<3)
{

   printf("the aarray is %s\n",arr[k]);
   fputs(arr[k],output);
   fputs("\n",output);
   k++;
}

} `

дополнительно спасибо Maddy

Ответы [ 3 ]

0 голосов
/ 21 июня 2011

Я написал что-то, что найдет дубликаты в произвольном строковом массиве и выведет имена. По вашему вопросу я не могу сказать, нужны ли вам конкретно индексы из исходного массива. Эта версия будет сортировать массив, а исходные индексы будут «потеряны». Но если вам нужно знать только имена, являющиеся дубликатами, должно работать следующее:

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

#define TRUE 1
#define FALSE 0

/* Compare function for quicksort. Shamelessly taken directly from linux man
 * page */
static int cmpstringp(const void *p1, const void *p2)
{
   return strcmp(* (char * const *) p1, * (char * const *) p2);
}

void find_duplicates(char *strings[], size_t size)
{
    size_t i, j, last_occurrence;
    int is_unique;

    for(i = 0; i < size; ++i)
    {
        /* This variable tells us if the current element is unique */
        is_unique = TRUE;
        for(j = i; j < size; ++j)
        {
            /* Make sure we aren't comparing the element to itself */
            if((j != i) && (strcmp(strings[i], strings[j]) == 0))
            {
                /* Since the array is sorted, we store the index of the last
                 * duplicate and continue our search from there.
                 */
                last_occurrence = j;
                is_unique = FALSE;
            }
        }

        /* The element was not unique, print the name */
        if(is_unique == FALSE)
        {
            printf("Duplicate: %s\n", strings[i]);
            /* Set the counter to the next element we must check for
                             * "uniqueness" */
            i = last_occurrence;
        }
    }
}

int main(int argc, char *argv[])
{
    /* Test array */
    char *test_array[] = { "test1", "test2", "test3", "test1", 
                                   "test4", "test1", "test4" };

    /* Sort it using quicksort to make the process of finding duplicates
     * easier
     */
    qsort(test_array, 7, sizeof(char*), cmpstringp);

    find_duplicates(test_array, 7);

    return 0;
}
0 голосов
/ 18 сентября 2011

Я думаю, что эта часть была бы корнем проблемы:

    while ((dit = readdir(dip)) != NULL)               
       {
           condition_var = dit->name;      
           a[i] = condition_var;  
                         i++;
       }

Я не уверен в том, как работает readdir (), но я бы предположил, что каждый раз он будет возвращать указатель временной структуры на dit,[i] сохраняет condition_var как указатель на имя.Вполне возможно, что позже будет сделан еще один вызов readdir (), который использует точно такое же пространство памяти для возврата временной структуры, перезаписывая пространство памяти, на которое указывал предыдущий condition_var.

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

    while ((dit = readdir(dip)) != NULL)               
       {
           int len = strlen(dit->name);
           condition_var = malloc(len+1);
           memncpy(condition_var, dit->name, len+1);
           //condition_var = dit->name;      
           a[i] = condition_var;  
                         i++;
       }

Не забудьте освободить каждый блок памяти, который вы вывели, в конце программы.(Или вы можете просто оставить все это для ОС, чтобы собрать мем - не рекомендуется).Код должен быть таким:

     int j; // use another loop indicator if you already declared j for other uses.
     for(j = 0; j<i; j++)   // i is the length of a[].
     {
         free(a[j]);   
         // no worry about a[j] being NULL. free() does nothing on a NULL pointer.
         a[j] = NULL;
     }
0 голосов
/ 21 июня 2011
char *a[20]; // an array of char pointers. 20 elements in the array.

char *findduplicates(char *arr[3],int count)
// arr is an array of char pointers, with 3 elements in the array.

findduplicates(a, count); // this will just pass 3 of the 20 pointers
// thus when you try to access a[3], it will probably seg-fault.

попробуйте это вместо:

char *findduplicates(char **arr,int count)

[править] Может быть, я ошибаюсь по этому поводу. Я только что написал небольшую тестовую программу, и она не потерпит крах, даже если объявить параметр функции как char *a[0]. Но все равно попробуйте мое предложение. Ошибки памяти не всегда приводят к сбоям в работе ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...