简体   繁体   中英

Checking NULL pointer segmentation fault in C

I have to split an initial char and create a list of said char which has to end with a NULL so i can iterate over in the main without knowing list size. The problem is that i get a seg fault whenever i try to check if last element is NULL. i am sorry i am still trying to learn both C and english. Thank you all

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

char **split(const char *s) {
    char **split;
    unsigned m_size = 0, c_size, i, j, k;

    // get s size
    for (i = 0; s[i] != '\0'; i++) {
        if (s[i] == ' ') {
            m_size++;
        }
    }
    m_size++;

    split = (char**) malloc(sizeof(char) * (m_size + 1));

    int sizes[m_size];
    c_size = 0;

    // get s words size
    for (i = 0, j = 0; s[i] != '\0'; i++) {
        if (s[i] == ' ') {
            c_size++;
            sizes[j] = c_size;
            c_size = 0;
            j++;
        } else {
            c_size++;
        }
    }
    sizes[j] = c_size;

    for (i = 0; i < m_size; i++) {
        split[i] = (char *) malloc(sizeof(char) * sizes[i]);
    }
    split[i] = NULL;

    for (i = 0, j = 0, k = 0; s[i] != '\0'; i++) {
        if (s[i] != ' ') {
            split[j][k] = s[i];
            k++;
        } else {
            split[j][k] = '\0';
            j++;
            k = 0;
        }
    }

    return split;
}

int main() {
    char s[19] = "hello how are you?";
    char **splitted;
    unsigned i;
    splitted = split(s);
    if (splitted == NULL) {
        return 1;
    }
    for (i = 0; splitted[i]!=NULL; i++) {
        printf("%s\n", splitted[i]);
    }
    return 0;
}

EDIT

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

char **split(const char *s) {
    char **r;
    unsigned word_size = 0;
    unsigned list_size = 0, i, j, k;

    // get s size
    for (i = 0; s[i] != '\0'; i++) {
        if (s[i] != ' ') {
            word_size++;
        } else {
            if (word_size > 0) {
                list_size++;
                word_size = 0;
            }
        }
    }
    list_size++;

    r = malloc(sizeof(*r) * (list_size + 1));

    int char_sizes[list_size];
    for (i = 0; i < list_size; char_sizes[i] = 0, i++);

    // get s words size
    for (i = 0, j = 0; s[i] != '\0'; i++) {
        if (s[i] != ' ') {
            char_sizes[j]++;
        } else {
            if (char_sizes[j] > 0) {
                j++;
            }
        }
    }

    for (i = 0; i < list_size; i++) {
        r[i] = malloc(sizeof(char) * char_sizes[i]);
    }
    r[i] = NULL;

    for (i = 0, j = 0, k = 0; s[i] != '\0'; i++) {
        if (s[i] != ' ') {
            r[j][k] = s[i];
            k++;
        } else {
            if (k > 0) {
                r[j][k] = '\0';
                j++;
                k = 0;
            }
        }
    }

    return r;
}

void destroy(char **list) {
    unsigned i;
    for (i = 0; list[i] != NULL; i++) {
        free(list[i]);
    }
    free(list);
}

int main() {
    char s[100] = " hello    guys how are?   you,d 31 3  ";
    char **splitted;
    unsigned i;
    splitted = split(s);
    if (splitted == NULL) {
        return 1;
    }
    for (i = 0; splitted[i]!=NULL; i++) {
        printf("%s", splitted[i]);
    }
    destroy(splitted);
    return 0;
}

ok guys i followed your tips and i edited my code. leaving this here if someone wants to point out other errors i will appreciate. now it should work even with multiple spaces. thanks to all

Your are requesting an "array" of pointers to char, but you are allocating an "array" of chars:

split = (char**) malloc(sizeof(char) * (m_size + 1));

should become

split = malloc(sizeof(char*) * (m_size + 1));

Note the sizeof(char*) . BTW: Note that in C, you should not cast the result of malloc as explained in this SO post.

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