简体   繁体   中英

I keep getting a segmentation fault and I'm not sure why

I'm pretty sure it has to do with my use of calloc() but I don't understand why. The objective of the program is for char* C to contain characters of char* A that are not in 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;
}

Initialization of a char* pointer may look like this:

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

This will assign the literal value 5 as the value of the A pointer. The A pointer will point (probably) to an invalid memory location.

The conversion (char*)(void*)(uintptr_t) (or somewhat similar conversion) may be done implicitly by the compiler. It's nice of the compiler to issue at least a warning about implicit conversion from an integer to a pointer.

Also you can "excess" the number of elements inside the { } brackets. Ie.:

char* A = { 1, 2, 3, 4, 5, };

The numbers 2, 3, 4, 5, are ignored, because char* may be initialized from one value only.

The compiler should warn you about those, ex. in gcc i get:

<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'};

So:

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

is equal to:

char *A = 113;

As q is equal to 113 according to the ascii table .

113 is an invalid pointer. Later in your code you do:

strlen(A)

which tries to access the memory behind the A pointer. As the pointer is invalid, it is undefined what happens. On your system, you get segmentation fault.

The A variable should probably be changed into an array:

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

or maybe equivalent:

char A[] = "qge";

Which will create an array of characters and initialize them with proper values.

You cannot initialize a pointer this way. char* A = {'q','g','e','\\0'}; It may seem to compile on some compilers, it is wrong to initialize this way. Please remember that pointer variables are like integral data type. It actually holds an integral value containing the address of a memory location.

Instead it should be delcared as array: char A = {'q','g','e','\\0'}; Array name itself behaves as a pointer in C.(with some limitations of course), So you pass the array name itself as argument to your functions.

Secondly considering your objective of the program: char* C to contain characters of char* A that are not in char* B,

the statement if(-1 != -1) seems like a typo error, i guess you meant

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

Also a typecast may be required at the calloc call as it returns void*

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

Considering all these things, below program will acheive your objective:

Hope this helps :)

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM