C ++ массив фиксированного размера, получающий значения мусора - PullRequest
0 голосов
/ 14 декабря 2018

Я пытался вращать струну по кругу на 1 смену.Вот простой код:

#include <bits/stdc++.h>
using namespace std;

int main() {
  string s = "1010";
  char a[s.length()];
  for (int i = 0; i < s.length() - 1; i++) {
    a[i] = s[i+1];
  }
  a[s.length()-1] = s[0];
  std::cout << a << '\n';
  std::cout << strlen(a) << '\n';
}

Когда я запускаю этот код, я получаю следующий вывод:

aditya@aditya-Inspiron-3558:~/miscCodes$ ./a.out 
0101�
6

Как меняется длина моего массива?А из-за мусорных значений?

Ответы [ 4 ]

0 голосов
/ 14 декабря 2018

Вы уже получили отличные ответы, так что это всего лишь дополнение.

#include <bits/stdc++.h> не является стандартным заголовочным файлом, и это сделает вас ленивым, поскольку включает в себя все, что вы, вероятно,нужно и многое другое .Включайте только те заголовки, которые вам нужны, особенно если вы собираетесь делать using namespace std;, что также является плохой идеей .

Кроме того, для решения проблемы с вращением элементов в вашемстрока, посмотрите на std :: rotate .Он может вращать не только строки, но и std::vector с и т. Д. Пример выполнения левого поворота на один шаг:

#include <iostream>
#include <algorithm> // std::rotate

int main() {
    std::string s = "1234";
    std::string cpy = s;

    //          first elem   new first elem   last elem
    std::rotate(cpy.begin(), cpy.begin() + 1, cpy.end());
    std::cout << s.size() << " " << s << "\n";
    std::cout << cpy.size() << " " << cpy << "\n";
}

Вывод

4 1234
4 2341
0 голосов
/ 14 декабря 2018

Во-первых, ваш код не является допустимым C ++, так как вы используете массивы переменной длины.Вместо этого используйте std::vector:

std::vector<char> a(s.length() + 1, 0); // Adding +1 to add space for the 0-terminated string

for (int i = 0; i < a.size() - 2; i++) { // Because of the null terminator and the first offset
  a[i] = s[i+1];
}
a[a.size()-2] = s[0];

Затем после вывода используйте data:

std::cout << a.data() << '\n';
std::cout << a.size() << '\n'; // Will give you +1 because we give the size of the container and not thew size of the string
0 голосов
/ 14 декабря 2018

Вместо этого символа a [s.length ()];

Сделайте этот символ a [s.length () + 1]

0 голосов
/ 14 декабря 2018

Массивы переменной длины (VLA) являются , а не частью стандарта C ++.Подробнее в Почему массивы переменной длины не являются частью стандарта C ++?


Но, скажем, вы используете расширение компилятора , которое позволяетпроблема в том, что вы используете здесь функцию C:

std::cout << strlen(a) << '\n';

, которая ожидает строку C, что означает NULL-оканчивающуюся строку .

Этоозначает, что вы должны сделать ваш массив достаточно большим, чтобы содержать символ завершения NULL, например:

char a[s.length() + 1];

, поскольку string::length() вернет 4 для строки "1010".Это означает, что строка C должна быть такой: «1010 \ 0», то есть фактическая строка, к которой добавляется завершающий символ NULL.В результате для хранения этой строки вам понадобится массив размера 5.

Простое исправление:

char a[s.length() + 1] = {0};

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

Другой подход заключается в назначении только терминатора NULL последней ячейке вашей строки, например a[s.length()] = '\0';.Обратите внимание, что s.length() теперь является индексом последнего элемента вашего массива.


Стандартные строковые функции C (например, strlen()) зависят от символа завершения NULL, который нужно пометитьконец строки.В отсутствие этого важного персонажа они не знают, когда остановиться, и, таким образом, получают доступ к памяти за пределами того места, которое они должны посетить.

Это вызывает Неопределенное поведение (UB), которое на вашем компьютере обращается к памяти со значениями мусора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...