C有人能告诉我这里发生了什么吗?

时间:2009-10-06 14:50:07

标签: c free malloc

我无法弄清楚这里到底发生了什么。我所期望的是输出应该说键中只有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;
}

输出: hithere \一个\ 2 \ 3 0 1 2 3 4 五 6 7 hithere \一个\ 2 \ 3 0 1 2 3 4 五 6 7

字符串正如我所期望的那样,但我认为只有0应该打印出来,因为0是我添加的唯一元素。我需要能够释放每个点而不是free [0]但是当我把free [i]放在for循环中打印出来的时候它会堆栈转储。

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

4 个答案:

答案 0 :(得分:4)

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

键是指向char的2个指针数组,但未初始化 试试这个

/* ... */
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

     
    

初始化程序:

         
      

赋值表达式
      {initializer-list}
      {initializer-list,}

    
         

initializer-list:

         
      

指定 opt 初始化程序
      initializer-list,指定 opt 初始值设定项

    
  

空初始化列表没有语法。

答案 1 :(得分:3)

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

答案 2 :(得分:1)

对于问题的第二部分,

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

char *keys[1000] = {0};

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

即使用

char *keys[1000] = {42};

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

答案 3 :(得分:1)

  

有什么区别   隐式初始化数组元素   为0并明确将它们设置为0   与memset()?

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

第一个选项(隐式初始化)将数组的每个元素设置为正确类型的零;第二个选项将所有元素的所有位(加上任何填充)设置为0.通常( 99.99%的当前计算机键入0 和<之间没有区别strong>所有位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" */