0

我无法弄清楚这里到底发生了什么。我期望的是输出应该说键中只有 1 个元素,当我只分配 120 字节的 0 位置时,它说有 7 个元素。

void add2(char **b, char *i) {
    if (!i) {
        b[0] = (char*) malloc(120);
        sprintf(b[0], "%s", "hithere");
    } else {
        strcat(b[0], "\\\\");
        strcat(b[0], i);
    }
}

void add1(char **b) {
    add2(b, NULL);
    add2(b, "one");
    add2(b, "two");
    add2(b, "three");
}

void add() {
    char *keys[2];
    int i;
    add1(keys);
    fprintf(stderr, "%s\n", keys[0]);
    for (i = 0; keys[i]; i++)
        fprintf(stderr, "%d\n", i);
    free(keys[0]);
}

int main (int argc, char** argv)
{   
     add();
     add();
     return 255;
}

输出:这里\一\二\三 0 1 2 3 4 5 6 7 那里\一\二\三 0 1 2 3 4 5 6 7

字符串和我期望的一样,但是我认为之后应该只打印 0,因为 0 是我添加的唯一元素。我需要能够释放每个位置,而不仅仅是 free[0],但是当我将 free[i] 放在打印出 i 的 for 循环中时,它会堆栈转储。

关于下面响应的初始化,如果我需要一个类似于 1000 而不是 2 的数组,那么如何在不输入 1,000 个 0 的情况下将它们全部初始化为 0

4

4 回答 4

4
/* ... */
void add() {
    char *keys[2];
/* ... */

keys 是一个包含 2 个指向 char 的指针的数组,但它没有被初始化
尝试这个

/* ... */
void add() {
    char *keys[2] = {0, 0}; /* explicit initialization of the two elements */
/* ... */

在所有成员都没有显式初始化器的情况下,未初始化的初始化器被初始化为零(其类型的正确零)。

/* ... */
void add() {
    char *keys[1000] = {42}; /* explicit initialize the first element to 42 */
                             /* and implicitly initialize all other elements to 0 */
                             /* **ATTENTION** */
                             /* initializing a pointer to 42 is wrong */
                             /* I only wrote that as an example */
/* ... */

编辑,引自标准

6.7.8 初始化
语法
1

初始化器:

赋值表达式
{ 初始化器列表 }
{ 初始化器列表 , }

初始化列表:

指定opt初始化器
initializer-list , 指定opt初始化器

空的初始化列表没有语法。

于 2009-10-06T14:57:44.367 回答
3

您尚未初始化键数组,因此它包含内存中发生的任何内容。在这种情况下,keys[1] 和最多 7 个不为零。

于 2009-10-06T14:56:25.413 回答
1

将数组元素隐式初始化为 0 和使用 memset() 将它们显式设置为 0 有什么区别?

char *data[1000] = {0};
memset(data, 0, sizeof data);

第一个选项(隐式初始化)将数组的每个元素设置为正确类型的零;第二个选项将所有元素的所有位(加上任何填充)设置为 0。通常(所有当前计算机的 99.99% )键入 0所有位 0之间没有区别。

想象一台具有分段内存的计算机......其中指针由两部分组成。当您将其设置为 0(0 的正确类型)时,编译器可以使该 0 与所有位 0 不同。如果您专门将所有位设置为 0,则最终可能会得到一个无效的指针。

void *test = 0; /* can make test something like "0xC0DE:0x0000" */
memset(test, 0, sizeof test); /* will make test as "0x0000:0x0000" */
于 2009-10-06T17:28:17.470 回答
1

对于问题的第二部分,

如果您需要初始化一个类似于 1000 而不是 2 的数组,请使用以下

char *keys[1000] = {0};

如果用一个值初始化数组的一个元素,那么数组的所有其他成员将自动初始化为零。

即,如果你使用

char *keys[1000] = {42};

然后数组的第一个成员将被初始化为 42,而数组的所有其他成员将自动初始化为零。

于 2009-10-06T16:58:07.250 回答