почему эта функция объединения C строк не работает - segfault? - PullRequest
0 голосов
/ 27 мая 2020

Это функция для поиска объединения строк.

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>



char* my_union(char* param_1, char* param_2)
{
    char *res[strlen(param_1) + strlen(param_2)];  //allocate long enough string

    //check if the letter is in result res string 
    for(int i = 0 ; i < strlen(param_1);i++){
        if(strchr(*res,param_1[i]) == NULL){// this checks for duplicates
            res[i] = param_1[i];
        }
    }

    for(int i = 0 ; i < strlen(param_2);i++){
        if (strchr(*res, param_2[i])== NULL){//this checks for duplicates too
            *res[i] = param_2[i];
        }
    }

    printf("%s\n", *res);
    return *res;

}


int main(){
    char *s1 = "zpadinton" ;
    char *s2 =  "paqefwtdjetyiytjneytjoeyjnejeyj";
    my_union(s1,s2);// must return "zpadintoqefwjy"
   //the union is zpadintoqefwjy
    return 0;
}

Ответы [ 2 ]

3 голосов
/ 27 мая 2020

Некоторые фундаментальные ошибки:

  • char *res[] - это массив указателей. Вы этого не хотите.

  • strlen(param_1) + strlen(param_2) недостаточно длинное, вы не выделили место для нулевого терминатора.

  • return *res; возвращать указатель на локальную переменную всегда неправильно, потому что эта переменная выходит за пределы области видимости, когда функция возвращается.

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

Примечательно, что поскольку вы неправильно использовали массив указателей, такие вещи, как res[i] = param_1[i];, не должны компилироваться чисто. Вы получите предупреждения "присвоение несовместимого типа" / "указатель целого числа без приведения" или что-то в этом роде.

Всегда читайте и исправляйте предупреждения. Для новичка предупреждение практически на 100% равно ошибке. Поднимите уровень предупреждений до максимума и, что еще лучше, заблокируйте компиляцию недопустимого кода. Например, gcc / clang / i cc: -std=c11 -pedantic-errors -Wall -Wextra -Werror.

0 голосов
/ 27 мая 2020

char * res [strlen (param_1) + strlen (param_2)]; // выделить достаточно длинную строку

Вы не можете выделить динамическую c длину в стеке. Вам нужно выделить его в куче, например:

char *res = malloc(strlen(param_1) + strlen(param_2)+1);

(Примечание: добавьте дополнительный байт для нулевого терминатора)

Вам необходимо установить буфер на нули, чтобы можно было использовать strchr позже:

memset(res, 0, strlen(param_1) + strlen(param_2)+1);

if (strchr (* res, param_1 [i]) == NULL) {// это проверяет наличие дублирует res [i] = param_1 [i]; }

strchr должен принимать res, а не *res. Присвоение индексу i не сработает, так как вам нужно добавить новый символ в конец строки результата.

int j=0;
for(int i = 0 ; i < strlen(param_1);i++){
    if(strchr(res,param_1[i]) == NULL){// this checks for duplicates
        res[j] = param_1[i];
        j++;
    }
}

for(i = 0 ; i < strlen(param_2);i++){
    if (strchr(res, param_2[i])== NULL){//this checks for duplicates too
        res[j] = param_2[i];
        j++;
    }
}

printf("%s\n", res);
return res;
...