Ошибка, вызванная "WRITE доступ к памяти" - PullRequest
0 голосов
/ 06 мая 2020

tbh Я думал, что выучить C будет несложно, так как я уже знаю несколько других языков, но у меня проблемы с кодом, и я не могу понять, как исправить эти ошибки . Я специализируюсь на Python, так что это сильно отличается из-за всех спецификаций для типов, указателей и т. Д. c. В любом случае, вот код ниже, извините, я бы вставил ошибку, но он не позволяет мне копировать вставку. Я использовал некоторые функции печати и обнаружил, что ошибка происходит из строки 9: «* returnStr + = * str» ;. Заранее благодарим за любую помощь.

#include <stdio.h>
#include <cs50.h>
#include <string.h>

char *multiplyString(const char *str, int num){
    char *returnStr = "";

    for (int i = 0; i < num; i++){
        *returnStr += *str;
    }

    return returnStr;
}

int main(void){
    bool asking = true;
    int height;
    const char *symbol = "#";
    while (asking == true){
        height = get_int("How tall should the pyramid be? pick a number between 1 and 8: ");
        if (8 >= height && height >= 1){
            asking = false;
        }
    }
    for (int i=1; i<=height; i++){
        printf("%s  %s\n", strcat(multiplyString(" ", height-i), multiplyString(symbol, i)), multiplyString(symbol, i));
    }
}

Ответы [ 2 ]

0 голосов
/ 06 мая 2020

Две проблемы:

  • Прежде всего, returnStr указывает на строковый литерал, который на самом деле является массивом только для чтения символов. В этом случае массив только из одного символа, являющегося ограничителем строки '\0'

  • Во-вторых, *returnStr += *str; не имеет смысла. Это то же самое, что и returnStr[0] = returnStr[0] + str[0]. А поскольку адрес назначения (returnStr[0]) является строковым литералом, попытка записи в него приводит к неопределенному поведению

Если вы хотите создать новую строку, содержащую num копий str, тогда вам нужно создать новую строку, содержащую не менее num * strlen(str) + 1 символов, +1 для терминатора. Затем вам нужно использовать strcat для объединения в эту новую строку.

Также, если вы распределяете память динамически (например, malloc), вам необходимо убедиться, что первый элемент инициализируется указателем конца строки.

0 голосов
/ 06 мая 2020

Замените multiplyString() на следующий

char *multiplyString(const char *str, int num) {
    // + 1 for null-terminator
    char *returnStr = calloc(sizeof(*returnStr), strlen(str)*num + 1);

    for (int i = 0; i < num; i++) {
        strcat(returnStr, str);
    }

    return returnStr;
}

Вы пытались изменить строковый литерал, что запрещено в C. Во-вторых, += не является конкатенацией строк в C; скорее, он пытался выполнить целочисленное сложение первого символа returnStr.

Чтобы исправить это, вы динамически выделяете надлежащий объем памяти, используя calloc() (который также инициализирует память до 0, что необходимо для strcat()). Затем на каждой итерации добавляйте строку, используя strcat(), в конец новой строки.

Не забудьте освободить строки, возвращаемые этой функцией, позже в программе, поскольку они выделяются динамически.

...