2011-11-03 126 views
3

我有一个指向struct的指针数组,并且出于任何原因,当我打印此数组时,其末尾有一个备用元素,从而导致代码在最后打印一个NULL字节。如何在C中将结构指针设置为NULL?

反正我有可以删除最后的存储块?

例如:

typedef struct 
{ 
    char *name; 
} B; 

typedef struct 
{ 
    B *var; 
} A; 

int main() { 
    int num = 5; //for example 
    A *foo = malloc(sizeof(A)); 
    B *bar = malloc(num * sizeof(B)); 
    for (int i = 0; i < num; i++) { 
     bar[i] = *create_b(&bar[i]); // some function that works. 
    } 
    foo->var = bar; 
    while (foo->var != NULL) { 
     printf("This is %s\n",foo->var->name); 
      foo->var++; 
    } 
} 

一切都被打印出来就好了,但有在循环结束不必要的打印。例如:

This is A 
This is B 
This is C 
This is D 
This is F 
This is 

显然该数组只有5个元素,最后一个不打印任何东西。

+0

检查数组是否为null,如果它是char数组作为struct的成员。它不应该打印它。除非您向我们展示代码实际上正在尝试,否则很难弄清楚。 – Mahesh

+0

你初始化了数组中的数据吗? – ziu

+0

你能向我们展示一个有关代码的例子吗?就像你如何定义数组,结构以及如何打印数组一样? –

回答

3

您的打印循环是:

foo->var = bar; 
while (foo->var != NULL) { 
    printf("This is %s\n",foo->var->name); 
    foo->var++; 
} 

foo->var永远等于NULL,因为你只是递增指针,所以你最终会读过去bar阵列的结束和你的应用程序可能会崩溃。

如果将while循环替换为for (int i = 0; i < num; i++),它将打印正确数量的元素。

+0

这就是我要找的:)谢谢你的答案。 – antiopengl

-1

你的问题可能是在功能create_b,你没有张贴。

编辑:不,这可能是错误的,对不起。

但可以肯定这是不是你想要的:

bar[i] = *create_b(&bar[i]); 

你们都在通栏的地址[i]和将其设置为任何的返回值点?

+0

它只设置'bar'的名字,打印出来就像你看到的那样。但循环只能从0到num? – antiopengl

+0

是的,我看到这不太对 - 看我的编辑? – usul

1

你不能这样做foo->var++,因为它被设置为NULL数组中没有的地方。此外,使用该++更改foo->var所以在循环foo->var不再指向数组的开始之后,并且您不能再次访问该数组。

您需要为结束阵列一些标记分配内存,就像琴弦有字符\0来标记字符串的结束。

尝试以下操作:

int main() { 
    int num = 5; //for example 
    A *foo = malloc(sizeof(A)); 
    B *bar = malloc((num + 1) * sizeof(B)); // +1 for array terminator 
    for (int i = 0; i < num; i++) { 
     bar[i] = *create_b(&bar[i]); // some function that works. 
    } 
    bar[i].name = NULL; // Use this as a marker to mean end of array 
    foo->var = bar; 
    for (B *tmp = foo->var; tmp->name != NULL; tmp++) { 
     printf("This is %s\n",tmp->name); 
    } 
} 

编辑在代码中有一些错误。