Почему моя числовая переменная изменяется после запуска функции ‘insert’?

#c

#c

Вопрос:

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

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

void Q1();
void Q1_Remove (char **ptr_string);
void Q1_Insert (char **ptr_string, int length);

int main()
{
    Q1();

    return 0;
}

void Q1 () {
    int number;
    printf("How many characters do you want to input: ");
    scanf("%d", amp;number);
    char *string = malloc(number   1);
    printf("Input the string: ");
    scanf("%s", string);
    printf("The string is: %sn", string);

    int option;
    do {
        printf("Do you want to 1-Insert, 2-Remove or 3-Quit: ");
        scanf("%d", amp;option);
        switch (option) {
            case 1:
                Q1_Insert(amp;string, number);
                break;
            case 2:
                Q1_Remove(amp;string);
                break;
        }
        if (option == 1 || option == 2) {
            printf("Resulting string: %sn", string);
        }
    } while (option == 1 || option == 2);

    free(string);
}

void Q1_Remove (char **ptr_string) {
    (*ptr_string)  ;
}

void Q1_Insert (char **ptr_string, int length) {
    int curr_len = strlen(*ptr_string);
    int i;
    printf("length is %d and curr_len is %d", length, curr_len);
    if (curr_len == length) {
        for (i = curr_len - 1; i > 0; --i) {
            *(ptr_string   i) = *(ptr_string   i - 1);
        }
    } else {
        (*ptr_string)--;
    }
    char to_insert;
    printf("What is the character you want to insert: ");
    scanf(" %c", amp;to_insert);
    **ptr_string = to_insert;
}
  

Мой терминальный ввод и вывод:

 How many characters do you want to input: 5
Input the string: abcde
The string is: abcde
Do you want to 1-Insert, 2-Remove or 3-Quit: 1
length is 5 and curr_len is 5
What is the character you want to insert: a
Resulting string: abcde
Do you want to 1-Insert, 2-Remove or 3-Quit: 1
length is 11212224 and curr_len is 5                     // length is weird here
What is the character you want to insert:
  

(ПРАВКА 2)
Удалена константа для переменной number и добавлена в объявление сверху. Отредактировано для добавления в заголовки!

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

1. Мы не видим изображения. Но в любом случае, пожалуйста, не публикуйте изображения текста. Вставьте ее непосредственно в виде текста в вопрос.

2. Это ваш фактический полный код? Вам нужно объявить функции до их вызова. Кроме того, что с тем const int number , что это явно не константа?

3. Да, это мой фактический полный код, и он выполнялся без объявления функций. Я пытался сделать number константой, поскольку он менялся на случайное число после 2-й вставки, но безрезультатно.

4. Он запускался, но теперь он не работал правильно, не так ли?

5. Спасибо за отзыв! Я отредактировал код, чтобы удалить константу перед целым числом и добавить в объявления, но все та же ошибка по-прежнему возникает.

Ответ №1:

В первую очередь проблема заключается в том, как вы перетасовываете символы в строке. Вы делаете это:

 for (i = curr_len - 1; i > 0; --i) {
    *(ptr_string   i) = *(ptr_string   i - 1);
}
  

Однако фактический указатель на строку *ptr_string . Поскольку вы используете ptr_string i , она обрабатывается ptr_string как массив указателей, и вы записываете по всей памяти стека после вашего string указателя, определенного в main . number Среди прочего, это приведет к снижению вашего значения.

Вместо этого вам нужно сделать это:

 *(*ptr_string   i) = *(*ptr_string   i - 1);
  

Лично я бы использовал вместо этого нотацию массива, которая гораздо более удобочитаема:

 (*ptr_string)[i] = (*ptr_string)[i - 1];
  

Или просто полностью удалите цикл и используйте. memmove