用零值初始化结构数组

Initialize struct array with zero value for all

我需要将我的结构数组初始化为零

我的结构:

typedef struct stud
{
    char nome[60];
    int num;
    int nota;
} Student;

typedef Student* CLASS;

我有这个代码:

int main(){
    CLASS cls;
    cls = (CLASS) calloc(100,sizeof(Student));
    if (cls==NULL) printf("Error allocating memory");
}

calloc 不应该将 cls 中的所有内容初始化为零吗?如果我打印 cls 或 cls[0] 我得到垃圾值;

由于讨论了这是如何发生的,这里是对原始代码的解释 post。

typedef struct stud
{
    char nome[60];
    int num;
    int nota;
} Student;
// This structure is most likely 68 bytes in size:
// sizeof(Student) == 68
// offsetof(Student, nome) == 0
// offsetof(Student, num) == 60
// offsetof(Student, nota) == 64

int main(){
    // Allocate an array of 100 Students, for a total of 6800 bytes.
    // Note that calloc fills the memory with zeroes.    
    Student *cls = calloc(100, sizeof(Student));
}

现在我们有一个用零填充的 6800 字节的数组。

让我们看一下 printf("%s") 个参数的所有选项。

"%s" 需要一个指向空终止字符串的 char* 指针。由于 printf 是可变参数函数,它不知道参数的真实类型, 它只会假定它们。

请注意,某些编译器可以检查 arg 类型,但这不是语言的一部分。

printf("%s", cls);

这里,cls 指向 6800 个零字节数组的开始。 ((char*)cls)[0] == '[=17=]',所以它立即终止,没有打印任何内容。

printf("%s", cls[0]);

由于 (char*)(cls[0]) 是一个空指针,这将因空指针取消引用而崩溃。程序会崩溃,但不会打印出垃圾。

printf("%s", cls[0]->nome);

这实际上相当于第一次打印,只是转换为不同的类型。但是由于 printf 从格式字符串而不是参数推断类型信息,所以它的行为是一样的。

printf("%s", &cls[5]->num);

这通常不是一个好主意,但它仍然不会打印任何内容。那是因为指针指向零初始化数组中的某处,这意味着当取消引用时,您仍然会先达到零。

打印垃圾的唯一方法是:

printf("%s", &cls);

这里我们传递一个指向cls的指针,说它是一个指向char数组的指针。假设 calloc 返回 0xdeadbeef,当取消引用双指针时,我们会将地址视为字符串,因此 printf 将打印出 0xef, 0xbe, 0xad, 0xde 的 ASCII 值以及它后面的任何内容,直到它命中a 0x00 或 moved 命中不属于该进程的地址并导致访问冲突。第一种情况更有可能。


编辑:显然其他答案和讨论主题已被删除。我会把它留在这里供以后的访客使用。