C ++静态数组初始化 - 内存问题

时间:2010-06-17 22:49:58

标签: c++

我有一个头文件,其中包含静态char数组的成员变量声明:

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

在CPP文件中,我将数组初始化为NULL:

char ABC::newArray[4] = {0};

在ABC构造函数中,我需要使用在运行时构造的值覆盖此值,例如整数的编码:

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]
}

当我从这个函数返回并打印修改后的newArray值时,它打印出的字符数多于数组声明中指定的4个字符。

任何想法为什么会这样。 我只想将char数组设置为4个字符,而不是更进一步。

...谢谢

6 个答案:

答案 0 :(得分:2)

你是如何打印的?在C ++(和C)中,字符串以nul结尾。 (\0)。如果您正在做类似的事情:

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

它将打印“uhoh”以及它运行的任何其他内容,直到它到达\0。您可能想要执行以下操作:

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

(顺便说一下,static与某个类的实例相关联并没有多大意义。另外,你可以= {},但是static之后不需要memset无论如何,变量都是零初始化的。最后,对于{{1}}来说没有任何意义,然后重写内容。)

答案 1 :(得分:1)

cout.write(arr, count_of(arr))

如果系统标头中未定义count_of

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

答案 2 :(得分:0)

您是否使用

之类的东西进行打印
printf("%s", newArray); //or:
cout << newArray;

?如果是这样,您需要在字符串末尾为nul-terminator留出空间。 C字符串只是字符数组,因此没有字符串长度的指示;处理字符串的标准库函数期望它们以nul(0)字符结束以标记结尾,因此它们将继续从内存中读取,直到找到它为止。如果你的字符串需要包含4个字符,那么它需要5个字节宽,这样你就可以将\0存储在第五个字节中

答案 3 :(得分:0)

除非使用自定义字符串数组输出方法,否则您需要带有0字节的第5个字符来标记4字符字符串的结尾。如果将值[3]设置为0以外的值,则将在静态数据区域中的newArray旁边开始打印字节。

也无需显式初始化静态数据。

使用valgrind的memcheck工具可以最好地捕获这些错误。

答案 4 :(得分:0)

它打印出一个字符串,该字符串从地址&amp; newArray [0]开始,然后在内存中的前0处结束(称为空终止符)。

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)

...全部为空终止,因为双引号中的任何内容都会在末尾添加空终止符

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

...不是以null结尾,单引号包含单个字符,不添加空终止符

以下是添加空终止符的示例...

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

答案 5 :(得分:0)

性能有点下降,你可以在'c-style'中加入4字节.. 打印4个字符或直到达到\ 0:

#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

顺便说一下,尝试使用std::stringstd::cout