Создать динамически распределенный массив C++

Я пытаюсь создать динамически выделяемый массив типа unsigned char* на C++. Однако, когда я это делаю, я возвращаю строку вместо заключенного в скобки ({}) массива, чего я хочу.

unsigned char* arr = new unsigned char[arrLen];

Код Изображение

Изображение, показывающее разницу между двумя

Вы видите, как последний не исчезает после первого символа? Это то, что я хочу.

Как я могу это исправить?

Спасибо за ваше время.

В чем проблема ?

Sid S 22.04.2018 07:36

Также интересно, в чем может быть проблема, не могли бы вы прояснить?

Alceste_ 22.04.2018 07:47

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

b23a 22.04.2018 07:47

Как вы думаете, почему это струна?

Galik 22.04.2018 07:48

А как вы думаете, что такое "массив, заключенный в скобки ({})"?

Galik 22.04.2018 07:49

Не уверен, в чем проблема. Но указатели беззнакового типа char * все время используются как массивы. Они интерпретируются как обычные данные и иногда используются для отображения графики с графическими данными. Но по-разному интерпретируются только при печати с такими командами, как cout. если, например, вы: char * str = "string" cout << str << endl; отобразит: строка. Если это не дает ответа на вопрос, укажите его более четко.

rauprog 22.04.2018 07:59

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

user4581301 22.04.2018 08:44

Теперь я понимаю, что отладчик мне «врет». Комментарий к сообщению RichieHindle по этой ссылке (stackoverflow.com/questions/972511/…) довольно хорошо подводит итог. Но разве нет способа заключить скобку динамического массива, как я показал, потому что до сих пор я мог делать это нормально со статическими массивами, а затем передавая функции ссылки на них. Я бы предпочел это, поскольку на данном этапе моего кода он был бы более однородным, а также потому, что некоторые функции действительно требуют наличия такого массива. Пример: у меня есть функция для проверки заголовка NT / DOS.

b23a 22.04.2018 08:54

Вы уверены, что ваш первый пример заканчивается вторым персонажем? Ваш отладчик может предполагать, что это строка при ее отображении. Что там говорится о содержимом arr [2]?

tdk001 22.04.2018 08:55

Вы действительно спрашиваете, как настроить отображение отладчика?

M.M 22.04.2018 09:04
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
249
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Во-первых, отладчик по умолчанию предполагает, что char представляет собой символ ascii, а не число. Он будет отображать char как таковой.

arr2 имеет тип const char[3], поэтому отладчик знает, что нужно отобразить 3 элемента.

arr имеет тип const char*. Отладчик не может знать, только ли это один элемент или массив с определенным количеством элементов.

Если вы, например, используете Visual Studio, вы можете указать отладчику, чтобы он отображал три символа, добавив «часы переменных» с синтаксисом arr,3 в меню часов.

Я не уверен, что это то, что вы ищете, но пробовали ли вы использовать std :: vector? Он может обрабатывать как минимум динамическое присваивание, которое вы ищете, и не должен рассматривать символ NULL как конец строки.

 #include <vector>

 std::vector<char> arr = { 0x5A, 0x00, 0x2B };

На самом деле я пробовал использовать std :: vector, когда начинал создавать свою программу, но с такими огромными массивами exe он вел себя забавно. Как будто он никогда не компилируется. Однажды я оставил его на ночь, но этого не произошло. Итак, я изменил его на массивы символов, затем во время компиляции он вышел из "CL.exe" с кодом 2, поэтому я попытался сделать массивы символов статическими, и тогда это сработало. Что касается вопроса, я не стал делать их статичными, но вы поняли. В любом случае, спасибо, это отлично подойдет для массивов, размер которых не превышает 10 МБ.

b23a 22.04.2018 09:03

Если вам нужен динамически растущий список символов (массив), вам нужен список указателей, в котором список каждого сегмента представляет собой большое число, скажем 1000. Класс векторного контейнера жертвует использованием памяти ради возможности роста.

векторный контейнерный класс допускает динамический рост, но использует много памяти

Кроме того, динамическое увеличение одного элемента данных за раз не рекомендуется для большого списка данных. Если вам нужен динамический рост для большого списка, создайте список по частям, например следующим. Используйте большой сегмент списка - скажем, 1000 единиц. В следующем примере я создал 1000 списков. Я делаю это, создавая массив из 1000 указателей. Это создаст 1 миллион искомых символов и может динамически расти. В следующем примере показано, как это сделать.

.

void main() {
    unsigned char* listsegment[1000];
int chrn=0;

    int x, y = 0;
    for (int x = 0; x < 1000; x++) {
        listsegment[x] = new unsigned char[1000];
        for (y = 0; y < 1000; y++) {
            *(listsegment[x] + y) = chrn;
if (chrn >=255) chrn=0;
else chrn++;
        }
    }

}

Завершение программы - Что делать, если необходимо динамически выделить более 1000 сегментов?

Затем создайте список наборов сегментов. Он может быть либо в связанном списке, либо в классе контейнера.

Поскольку один набор создает 1000 сегментов по 1000 символов, набор этих наборов, вероятно, не должен превышать 1000. Наборы из тысяч будут равны (1000 * 1000) * 1000, что будет равно одному миллиарду. Следовательно, коллекция должна быть только 1000 или меньше, что может быть быстро повторено, что делает случайный доступ к коллекции ненужным.

Вот программа, переделанная для поддержки бесконечного количества наборов через бесконечно большой набор наборов. Это также хороший пример сегментированного распределения динамической памяти в целом.

#include <iostream>
#include<queue>

using namespace std;

struct listSegmentSetType {
    unsigned char* listSegment[1000];
    int count=0;
};


void main() {

    listSegmentSetType listSegmentSet;
    queue<listSegmentSetType> listSegmentSetCollection;
    int numberOfListSegmentSets = 0;

    int chrn = 0;

    int x, y = 0;
    listSegmentSet.count = 0;
    for (int x = 0; x < 1000; x++) {

        listSegmentSet.listSegment[x] = new unsigned char[1000];
        for (y = 0; y < 1000; y++) {
            *(listSegmentSet.listSegment[x] + y) = chrn;
            if (chrn >= 255) chrn = 0;
            else chrn++;
        }
        listSegmentSet.count++;
    }

    // add just completely filled out first list segment set to que
    listSegmentSetCollection.push(listSegmentSet);
    numberOfListSegmentSets++;

    // now fill in second set of list segments-

    listSegmentSet.count = 0;

    for (int x = 0; x < 1000; x++) {

            listSegmentSet.listSegment[x] = new unsigned char[1000];
        for (y = 0; y < 1000; y++) {
            *(listSegmentSet.listSegment[x] + y) = chrn;
            if (chrn >= 255) chrn = 0;
            else chrn++;
        }
        listSegmentSet.count++;
    }
    listSegmentSetCollection.push(listSegmentSet);
    numberOfListSegmentSets++;

    // now fill out any more sets of list segments and add to collection 
    // only when count listSegmentSet.count is no
    // longer less than 1000.  
}

-1 Этот ответ никак не затрагивает вопрос. Взгляните на std::deque, чтобы найти аналогичные блоки контейнера библиотеки данных.

user4581301 22.04.2018 17:59

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

rauprog 23.04.2018 09:53

Другие вопросы по теме