Написание функции быстрой фильтрации для символа ** - PullRequest
0 голосов
/ 31 марта 2011

Я пытаюсь написать быструю функцию для фильтрации символа ** и помещения результатов в другой символ **

Это то, что я написал:

/*
   -filterable is what is to be filtered
   -filter is the filter
   -filtered is the result applying the filter to filterable
*/
void filter(const char** filterable,const char * filter,char** filtered)
{
    memset(filtered,'\0',sizeof(filtered));
    int i=0;
    int j=0;
    int filter_length=strlen(filter);
    int items=sizeof(filterable)/sizeof((char *) filterable); //segfault?

    while(items--)
    {
        if((strncmp(filter,filterable[i],filter_length)==0))
            strcpy(filtered[j++],filterable[i]);

        i++;
    }
}

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

Пост-комментарии:

Хорошо, я читаю все комментарии, и, кажется, нижеработатьУчитывая, что это нужно быстро, я добавил ключевое слово register, хотя слышал, что в наши дни это ничего не гарантирует.

void filter(char ** filterable, const char * filter, char ** filtered, int filters)
{
    register int i=0;
    register int j=0;
    int filter_length=strlen(filter);

    while(filters--)
    {
        if((strncmp(filter,filterable[i],filter_length)==0))
           strcpy(filtered[j++],filterable[i]);

        i++;
    }
}

Ответы [ 3 ]

2 голосов
/ 31 марта 2011

Вы путаете указатели, массивы и то, на что указывают указатели.

memset(filtered, '\0', sizeof(filtered)); вероятно дает вам ошибку. filtered имеет тип char **, что означает, что sizeof(filtered) - это размер указателя, а не чего-либо, на что указывает, и вы устанавливаете filtered, который является указателем на char *, на ноль. Это неопределенное поведение, но на большинстве современных компьютеров filtered устанавливает нулевой указатель. Вам нужно выделить память для того, на что указывает filtered, и на что указывают эти char *, и вам нужно указать, насколько велик filtered и насколько велики строковые области, на которые он указывает.

Поскольку filtered содержит недопустимый адрес памяти, strcpy() пытается что-либо он или что-то, на что он якобы указывает, попытается получить к нему доступ, и это, как правило, приведет к ошибке на машине Unix / Linux.

sizeof(filterable)/sizeof(char *) filterable) не делает ничего полезного. Если бы filterable был массивом, sizeof(filterable)/sizeof(*filterable) дал бы вам количество элементов в filterable. Однако, даже если он изначально был массивом, он передается как указатель и теряет всю информацию о количестве содержащихся в нем элементов.

2 голосов
/ 31 марта 2011

Вы не можете использовать sizeof (char **) (поскольку функция фактически получает), см. этот вопрос SO . Вы должны указать длину массива в качестве параметра функции.

0 голосов
/ 31 марта 2011

sizeof (фильтруется) будет 4 на обычной 32-битной машине. То есть sizeof (char **) == 4. Это то, что вы ищете, когда вызываете memset (фильтруется, '\ 0', sizeof (фильтруется))?

Сегфоут может быть вызван тем, что фильтруется == 0x0000 после вызова memset ().

- Пит

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