0

I'm trying to create a dynamically allocated array of type unsigned char* in C++. However, when I this I get back a string instead of a bracket enclosed ({}) array which is what I want.

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

Code Picture

Picture showing the difference between the two

You see how the latter doesn't just go to nothing after the first character? That's what I want.

How might I go about remedying this?

Thank you for your time.

b23a
  • 3
  • 3
  • 1
    What is the problem ? – Sid S Apr 22 '18 at 05:36
  • Also wondering what the problem might be, can you please clarify ? – Alceste_ Apr 22 '18 at 05:47
  • I don't want it to be a string. The function I'm passing this into needs a bracket enclosed list. For context, the contents of `arr` will be an executable in hex format. Executables contain a lot of null bytes to which adds to the weirdness if interpreted as a string because they strings interpret those as the end of the string. – b23a Apr 22 '18 at 05:47
  • Why do you think it is a string? – Galik Apr 22 '18 at 05:48
  • And what do you think "a bracket enclosed ({}) array` is? – Galik Apr 22 '18 at 05:49
  • Not sure what the problem is. But unsigned char* type pointers are used to be arrays all the time. They are interpreted as regular data and are sometimes used to display graphics with graphics data. But are only interpreted differently when printing with commands such as cout. if for instance you: char* str="string" cout << str << endl; would display: string . If this doesn't answer the question, please specify the question more clearly. – rauprog Apr 22 '18 at 05:59
  • You're chasing a phantom. The debugger does not know how big an array, or even if there is an array, at the other end of that pointer, so all it can do is assume a character string and show you everything up to the null terminator. – user4581301 Apr 22 '18 at 06:44
  • I realize now that the debugger is "lying" to me. The comment on the post by RichieHindle at this link (https://stackoverflow.com/questions/972511/view-array-in-visual-studio-debugger) sums it up pretty well. But is there no way of having a dynamic array bracket enclosed like I showed because up until now I've been able to do that fine with static arrays then passing functions the reference to it. I would prefer this as at this point in my code it would be more uniform as well as because some functions do require having the array like that. Ex: A function I have for checking the NT/DOS header – b23a Apr 22 '18 at 06:54
  • Are you sure your first example is ending on the second character? Your debugger may be assuming it is a string when displaying it. What does it say the contents of arr[2] is? – tdk001 Apr 22 '18 at 06:55
  • Are you actually asking about how to configure the debugger display? – M.M Apr 22 '18 at 07:04

3 Answers3

2

First, de debugger assumes by default that char represents an ascii character rather than a number. It will display char as such.

arr2 has type const char[3] so the debugger knows there are 3 elements to display.

arr has type const char*. The debugger can't know if it's only one elements or an array with a certain number of elements.

If you are using visual studio for instance, you can hint the debugger to display three char by adding a “variable watch” with the syntax arr,3 in the watch menu.

Guillaume Gris
  • 2,135
  • 17
  • 34
2

I'm not sure if this is what you are looking for, but have you tried using a std::vector? It can handle the dynamic assignment you are looking for at least, and shouldn't treat a NULL character as the end of a string.

 #include <vector>

 std::vector<char> arr = { 0x5A, 0x00, 0x2B };
tdk001
  • 1,014
  • 1
  • 9
  • 16
  • I actually tried using std::vector when I began creating my program but it acted funny with such huge exe arrrays. Like it would never compile. I left it overnight once and it never did. So I changed it to char arrays then my during compilation it exited "CL.exe" exited with code 2 so I tried making the char arrays static and then it worked. In the question, I didn't bother making them static but you get the point. Thanks anyways though, this would work great for arrays that aren't 10 MBs in size surely. – b23a Apr 22 '18 at 07:03
-1

If you want a list of chars(array) that grows dynamically, what you need is a list of pointers where the list of each segment is a large number-say 1000. A vector container class sacrifices memory usage for the ability to grow.

vector container class allows for dynamic growth but uses a lot of memory

Also, dynamic growth one data element at a time is not recommended for a large list of data. If you want dynamic growth for a large list, create a list in chunks such as the following. Use a large list segment- of say 1000 units. I created 1000 lists in the following example. I do this by creating an array of 1000 pointers. This will create the 1 million chars you are looking for and can grow dynamically. The following example shows how you would do this.

.

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++;
        }
    }

}

Completing the program- What if more than 1000 segments need to be dynamically allocated?

Then create a list of Segment Sets. It can either be in a linked list or a in a container class.

Since the single set creates a 1000 segments of 1000 characters, a collection of these sets needs probably not be larger than 1000. A thousands sets would equal (1000*1000)*1000 which would equal one billion. Therefore, the collection would only need to be 1000 or less, which can be quickly iterated through-which makes random access for the collection not necessary.

Here is the program redone to support an infinite amount of sets through an infinitely large collection of sets. This also is a good example of segmented dynamic memory allocation in general.

#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.  
}
rauprog
  • 243
  • 3
  • 9
  • -1 This answer does not address the question in any meaningful way. Take a look at `std::deque` for a similar blocks of data library container. – user4581301 Apr 22 '18 at 15:59
  • Yep. I know there is a container class that is a list class. Was also going to mention to do a doubly linked list. So it answers the question in plenty of a meaningful way-but just didn't include a doubly linked list because I thought that would take too much of my time and over answering the question. – rauprog Apr 23 '18 at 07:53