Печать массива с указателем на C

#c #dynamic #printf #allocation

#c #динамический #printf #выделение

Вопрос:

У меня есть указатель на массив char , и мне нужно распечатать весь массив (не один за другим, а весь массив). У меня ошибка: zsh: segmentation fault . Я не понимаю, почему. Мой код берет текст stdin и помещает символы в массив. Если первый массив char_array недостаточно велик, я помещаю их во второй вызываемый bigger_array .

 int main() {
    int c;
    int index = 0;
    size_t size = 100;                        
    char *char_array = malloc(size * sizeof(char)); 
    if (char_array != 0) {
        while ((c = getchar()) != EOF amp;amp; index < size) {
            char_array[index] = c;
            index  ;
        }
        size_t newSize = size * 100;
        char *bigger_array = realloc(char_array, newSize * sizeof(char)); 
        if (bigger_array != 0) {
            bigger_array = char_array;
            while ((c = getchar()) != EOF amp;amp; index < newSize) {
                bigger_array[index] = c;
                index  ;
            }
            size = newSize;
        }
    }
    printf(*char_array);
    return 0;
}
  

Комментарии:

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

2. Попытка напечатать то, на что указывает char_array when char_array == 0 , плоха.

3. При распечатке массива лучше всего использовать цикл, но вам нужно просмотреть свой код, что вы хотите проверить с помощью char_array != 0 , если вы перераспределяете память для нового указателя char, почему тогда у вас есть bigger_array = char_array ?. Кроме того, вы не берете файл из stdin

Ответ №1:

  • bigger_array = char_array; должно быть char_array = bigger_array; . В противном случае указатель на вновь выделенный буфер перезаписывается указателем на старый буфер, и произойдет что-то плохое.
  • printf(*char_array); плохо, потому что он передает целое число (один символ), где требуется указатель. Так и должно быть printf("%.*s", index, char_array); . Обратите внимание, что длина для печати указана, и благодаря этому вам не нужно добавлять завершающий нулевой символ.

Ответ №2:

В вашем коде есть несколько проблем:

  • вы не включаете <stdio.h> ни <stdlib.h>
  • вы должны освободить char_array и сохранить big_array , чтобы char_array so char_array указывал на больший выделенный массив.
  • printf(*char_array) имеет неопределенное поведение по нескольким причинам. Вы можете печатать символы с fwrite(char_array, 1, index, stdout) помощью или с printf("%.*sn", (int)index, char_array) помощью .
  • нет необходимости в отдельных циклах, просто перераспределите массив по требованию.

Вот модифицированная версия:

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

int main() {
    int c;
    size_t index = 0;
    size_t size = 100;
    char *char_array = malloc(size);
    if (char_array != NULL) {
        while ((c = getchar()) != EOF) {
            if (index == size) {
                size_t new_size = size   size / 2   size / 8; /* increase by the golden ratio */
                char *new_array = realloc(char_array, new_size);
                if (new_array == NULL) {
                    fprintf(stderr, "out of memoryn");
                    free(char_array);
                    return 1;
                }
                size = new_size;
                char_array = new_array;
            }
            char_array[index  ] = c;
        }
        printf("%.*sn", (int)index, char_array);
    }
    return 0;
}
  

Ответ №3:

Рассмотрите это как комментарий ^^

Я советую вам использовать флаги для предупреждения с вашим исполнителем. например gcc , флаги -W -Wextra -Wshadow for удобны в использовании и предотвращают потерю времени.