开发者

C++ Static Array Initialization - Memory Issue

I have a header file which contains a member variable declaration of a static char array:

class ABC 
{ 
public:
static char newArray[4];
// other variables / functions
private:
void setArray(int i, char * ptr);
}

In the CPP file, I have the array initialized to NULL:

c开发者_如何学Pythonhar ABC::newArray[4] = {0};

In the ABC constructor, I need to overwrite this value with a value constructed at runtime, such as the encoding of an integer:

ABC::ABC()
{ 
int i; //some int value defined at runtime
memset(newArray, 0, 4); // not sure if this is necessary
setArray(i,newArray);
} 

...

void setArray(int i, char * value)
{
    // encoding i to set value[0] ... value [3]
}

When I return from this function, and print the modified newArray value, it prints out many more characters than the 4 specified in the array declaration.

Any ideas why this is the case. I just want to set the char array to 4 characters and nothing further.

Thanks...


How are you printing it? In C++ (and C), strings are terminated with a nul. (\0). If you're doing something like:

char arr[4] = {'u', 'h', 'o', 'h'};
std::cout << arr;

It's going to print "uhoh" along with anything else it runs across until it gets to a \0. You might want to do something like:

for (unsigned i = 0; i < 4; ++i)
    std::cout << arr[i];

(Having a static tied to instances of a class doesn't really make sense, by the way. Also, you can just do = {}, though it's not needed since static variables are zero-initialized anyway. Lastly, no it doesn't make sense to memset something then rewrite the contents anyway.)


cout.write(arr, count_of(arr))

If count_of isn't defined in a system header:

template<typename T, size_t N>
inline size_t count_of(T (&array)[N]) { return N; }


Are you printing it using something like

printf("%s", newArray); //or:
cout << newArray;

? If so, you need to leave space for the nul-terminator at the end of the string. C strings are just arrays of characters, so there's no indication of the length of the string; standard library functions that deal with strings expect them to end in a nul (0) character to mark the ending, so they'll keep reading from memory until they find one. If your string needs to hold 4 characters, it needs to be 5 bytes wide so you can store the \0 in the fifth byte


You'll need a 5th character with a 0 byte to mark the end of the 4 character string, unless you use custom char-array output methods. If you set value[3] to something other than 0, you'll start printing bytes next to newArray in the static data area.

There's also no need to explicitly 0 initialize static data.

You can best catch those kinds of errors with valgrind's memcheck tool.


It is printing out a string that starts at the address &newArray[0] and ends at the first 0 in memory thereafter (called the null terminator).

char strArr[] = {"Hello"};
char strArr[] = {'H', 'e', "llo");
char strArr[] = "Hello";
char* strArr = "Hello"; // careful, this is a string literal, you can't mess with it (read-only usually)

...are all null terminated because anything in double quotes gets the null terminator tacked on at the end

char strArr[] = {'H', 'e', 'l', 'l', 'o'};

...is not null terminated, single quotes contain a single character and do not add a null terminator

Here are examples of adding a null terminator...

strArr[3] = '\0';
strArr[3] = NULL;
strArr[3] = 0;


With a bit loss of performance, you can fit into 4 byte.. in 'c-style'.
Print either 4 characters or until \0 is reached:

#include <cstdio>
#include <cstring>
...
//calculate length
size_t totalLength = sizeof(ABC::newArray) / sizeof(ABC::newArray[0]);
char* arrayEnd     = (char*)memchr(ABC::newArray, '\0', totalLength);
size_t textLength  = arrayEnd != 0 ?
                     arrayEnd-ABC::newArray : totalLength;
//print
fwrite(
       ABC::newArray, //source array
       sizeof(ABC::newArray[0]), //one item's size
       textLength, //item count
       stdout); //destination stream

By the way, try to use std::string and std::cout.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜