strlen segfaults на 2d динамических c массив строк - PullRequest
0 голосов
/ 01 марта 2020

Почему я получаю segfault, когда пытаюсь напечатать strlen строки, которая является частью массива строк? Я могу напечатать каждую строку - printf работает отлично. Но почему strlen вызывает segfault?

Приведенная ниже программа сначала получает вход n, то есть количество строк, которые я хочу динамически распределить. Затем я выделяю место для 32 байтов для каждой строки

int main() {
    int i;
    int n;
    char **nums;
    scanf("%d", &n);
    printf("n = %d\n", n);
    nums = malloc(sizeof(char *) * n);
    printf("allocated nums\n");
    for(i=0; i<n; i++) {
        nums[i] = malloc(sizeof(char) * 32);
        memset(nums[i], '\0', sizeof(char) * 32);
    }
    for(i=0; i < n; i++) {
        scanf("%s", &nums[i]);
    }

    for(i=0; i<n; i++) {
        // THIS PRINTS FINE
        printf("string = %s\n", &nums[i]);
        // SEGFAULT HERE IMMEDIATELY
        printf("length = %d\n", strlen(nums[i]));
    }

Вот вывод консоли. В качестве теста я ввел n = 3, за которыми следуют цифры 45, 46 и 47:

3
n = 3
allocated nums
45
46
47
string = 45
Segmentation fault (core dumped)

Кроме того, я получаю ошибку segfault, когда пытаюсь получить доступ к отдельному символу в каждой строке. Опять же, первый printf во external для l oop печатает строку, затем я получаю segfault с доступом к nums [i] [k]:

    int i, k=0;
    for(i=0; i<n; i++) {
        printf("Printiiing: %s\n", &nums[i]);
        // WHY DOES THIS SEGFAULT???
        //printf("first char = %c\n", nums[i][0]);
        while(k<32 && nums[i][k] != '\0') {
            // THIS CAUSES A SEG FAULT
            printf("char = %c", (nums[i])[k]);
            k++;
        }
    }

Ответы [ 2 ]

0 голосов
/ 01 марта 2020

Существует указатель разницы между адресами &nums[i] и nums[i]. Вы можете проверить с помощью strlen((const char*)(&nums[i])), чтобы получить длину.
Объяснение @Employee из России точно по причине.

0 голосов
/ 01 марта 2020

Это нормально:

    for(i=0; i<n; i++) {
        nums[i] = malloc(sizeof(char) * 32);
        memset(nums[i], '\0', sizeof(char) * 32);
    }

После этого l oop, каждый nums[i] является указателем на 32-байтовый буфер.

Но это повреждает (перезаписывает) все указатели, вместо чтения строк в выделенные буферы:

    for(i=0; i < n; i++) {
        scanf("%s", &nums[i]);
    }

Чтобы исправить ошибку, используйте: scanf("%s", nums[i]);.

...