猜猜输出。 (字符数组的声明/初始化)

时间:2013-05-21 09:53:42

标签: c++

这是一段代码。我正在使用g ++

void initialize(int p, char a[], char b[])
{
    for(int i=0;i<6*p;i++)
    {
        a[i]='-';
        b[i]='-';
    }
}

int main()
{
    int p=9;
    char a[2*p],b[4*p];
    initialize(p,a,b);
    cout<<a<<endl<<b<<endl;
}

这里,声明a和b的方式......它们的大小分别为18和36。但它们并没有在输出中看到。发生了什么事?

Output:
------------------------------------------------------
------------------------------------------------------------------------------------------------------

4 个答案:

答案 0 :(得分:2)

您的初始化远远超出了为ab分配的内存范围

你需要做

for(int i = 0; i < 2*p; ++i) {
    a[i]='-';
}

for(int i = 0; i < 4*p; ++i) {
    b[i]='-';
}

分配给你自己的内存之外的内存可以做任何事情。就像给你的狗发传真一样。

答案 1 :(得分:0)

char a[2*p] will have 2*9=18 characters max.
char b[4*p] will have 4*9=36 characters max.

initialize创建6 * 9 = 54个字符,但每个对象都接受其自己的限制。你想在这做什么?

答案 2 :(得分:0)

您的for循环:

for(int i=0;i<6*p;i++)

将数组大小视为示例6*p中的p==9。所以你的循环将数组大小视为54。

但是数组a只有18个元素,因此你的初始化会溢出这个数组。

数组b只有36个元素,所以你的初始化也会溢出这个数组。

溢出一个数组会写入你可能不打算写入的内存,这会导致各种错误......

你最好使用像这样的功能。你还需要 NULL-terminate 你的字符串吗?

void initialize(char a[], size_t aSize, char b[], size_t bSize)
{
    int i = 0;
    for(; i < aSize-1; i++)
        a[i]='-';
    for(i = 0; i < bSize-1; i++)
        b[i]='-';

    // I think you need to NULL terminate....
    a[aSize-1] = '\0';
    b[bSize-1] = '\0';
}

int main()
{
    int p=9;
    char a[2*p],b[4*p];
    initialize(a, sizeof(a), b, sizeof(b));

    std::cout << a << std::endl << b << std::endl;
    return 0;
}

如果您使用的类型为main()的数组,则在char函数中更为一般......

initialize(a, sizeof(a)/sizeof(a[0]), b, sizeof(b)/sizeof(b[0]));

甚至,要初始化数组只需使用 memset(),然后就不需要函数initialize() :)

E.g。

#include <string.h>

int main()
{
    int p=9;
    char a[2*p],b[4*p];

    memset(a, '-', sizeof(a)-1);
    a[sizeof(a)-1] == '\0';
    memset(b, '-', sizeof(b)-1);
    b[sizeof(b)-1] == '\0';

    std::cout << a << std::endl << b << std::endl;
    return 0;
}

我刚才的另一件事是“你是 NULL - 终止你的字符串吗?我已经改变了上面的例子来迎合它,否则当打印字符串时,打印功能不会知道在哪里停下来!

另一个选项可能还有std::fill()*std::fill_n()*

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

int main(int argc, char* argv[])
{
    int p=9;
    char a[2*p],b[4*p];

    std::fill_n(a, sizeof(a)-1, '-');
    a[sizeof(a)-1] = '\0';

    std::fill_n(b, sizeof(b)-1, '-');
    b[sizeof(b)-1] = '\0';

    std::cout << a << std::endl << b << std::endl;
    return 0;
}

答案 3 :(得分:0)

您获得的输出只是因为您没有null终止字符串。如果以其他方式放置代码,则可能无法获得与现在相同的输出。只是你继续初始化数组出界,不知何故两个数组彼此靠近,cout寻找下一个'\0'直到它打印的位置。

只需null终止数组,然后一切都很好。