Я продолжаю получать ошибки сегментации, и я не уверен, почему - PullRequest
0 голосов
/ 28 февраля 2019

Я почти уверен, что это связано с моим использованием calloc (), но я не понимаю, почему.Цель программы состоит в том, чтобы char* C содержал символы char* A, которых нет в char* B.

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

char* diff(char* A, char*B);

int main() {
  char* A = {'q','g','e','\0'};
  char* B = {'a','d','e','\0'};
  char* C = diff(A,B);
  printf("%s", C);
  free(C);
  return(0);
}

int search(char* S, char c) {
    int i=0;

    while( S[i]!='\0' ){
        if( S[i]==c ) break;
        i++;
    }
    if( S[i]=='\0' ) return -1;
    else return i;
}

char* diff(char* A, char* B) {
    int i;
    char* C = calloc(strlen(A), sizeof(char));
    assert(C != NULL);
    int lengthC = 0;

    for (i = 0; i < strlen(A); i++) {
        if (-1 != -1) {
            C[lengthC] = A[i];
            lengthC++;
        }
    }

    C[lengthC] = '\0';
    return C;
}

Ответы [ 2 ]

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

Вы не можете инициализировать указатель таким образом.char * A = {'q', 'g', 'e', ​​'\ 0'};Может показаться, что компиляция на некоторых компиляторах, неправильно инициализировать этот путь.Пожалуйста, помните, что переменные-указатели подобны целочисленному типу данных.На самом деле он содержит целочисленное значение, содержащее адрес ячейки памяти.

Вместо этого он должен быть разделен как массив: char A = {'q', 'g', 'e', ​​'\ 0'};Само имя массива ведет себя как указатель на C. (с некоторыми ограничениями, конечно), поэтому вы передаете само имя массива в качестве аргумента своим функциям.

Во-вторых, учитывая вашу цель программы: char * C содержитсимволы char * A, которых нет в char * B,

утверждение if (-1! = -1) похоже на ошибку опечатки, я думаю, вы имели в виду

if (search (B, A [i]) == -1)

Кроме того, при вызове calloc может потребоваться преобразование типа, поскольку оно возвращает void *

char * C = (char *) calloc (strlen)(A), sizeof (char));

Учитывая все это, приведенная ниже программа достигнет вашей цели:

Надеюсь, это поможет:)

int main() {
    char A[] = { 'q','g','e','\0' };
    char B[] = { 'a','d','e','\0' };
    char* C = diff(A, B);
    printf("%s", C);
    free(C);
    return(0);
    }

int search(char* S, char c) {
    int i = 0;

    while (S[i] != '\0') {
        if (S[i] == c) break;
        i++;
        }
    if (S[i] == '\0') return -1;
    else return i;
}

char* diff(char* A, char* B) {
    int i;
    char* C = (char *) calloc(strlen(A), sizeof(char));
    assert(C != NULL);

    int lengthC = 0;

    for (i = 0; i < strlen(A); i++) {
        if (search(B,A[i]) == -1) {
            C[lengthC] = A[i];
            lengthC++;
        }
    }

    C[lengthC] = '\0';
    return C;
}
0 голосов
/ 28 февраля 2019

Инициализация указателя char* может выглядеть следующим образом:

char *A = { (char*)(void*)(uintptr_t)5 };

Это присвоит буквальное значение 5 в качестве значения указателя A.Указатель A будет указывать (вероятно) на неверную ячейку памяти.

Преобразование (char*)(void*)(uintptr_t) (или несколько похожее преобразование) может быть выполнено неявно компилятором.Приятно, чтобы компилятор выдавал хотя бы предупреждение о неявном преобразовании целого числа в указатель.

Также вы можете «увеличить» количество элементов в скобках { }.Т.е.: * 10101

char* A = { 1, 2, 3, 4, 5, };
1017 * Числа 2, 3, 4, 5, игнорируются, поскольку char* можно инициализировать только из одного значения.

Компилятор должен предупредить вас об этом, напр.в gcc я получаю:

<source>:6:16: warning: incompatible integer to pointer conversion initializing 'char *' with an expression of type 'int' [-Wint-conversion]
    char* A = {'q','g','e','\0'};
               ^~~
<source>:6:20: warning: excess elements in scalar initializer
    char* A = {'q','g','e','\0'};

Итак:

char* A = {'q','g','e','\0'};

равно:

char *A = 113;

Как q равно 113 в соответствии с таблица ascii .

113 - недопустимый указатель.Далее в вашем коде вы делаете:

strlen(A)

, который пытается получить доступ к памяти за указателем A.Так как указатель недействителен, то, что происходит, не определено.В вашей системе вы получаете ошибку сегментации.

Переменная A, вероятно, должна быть преобразована в массив:

char A[] = {'q','g','e','\0'};

или, возможно, эквивалентный:

char A[] = "qge";

Который создаст массив символов и инициализирует их правильными значениями.

...