C 初始化结构数组,使其全部为零值

C 初始化结构数组,使其全部为零值,c,arrays,struct,C,Arrays,Struct,我需要将我的结构数组序列化为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 allo

我需要将我的结构数组序列化为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],我会得到垃圾值

既然有人讨论过这是如何发生的,下面是原始帖子中对代码的解释

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”需要指向以null结尾的字符串的char*指针。由于printf是一个变量arguments函数,它不知道参数的真正类型, 它只会假设它们

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

printf("%s", cls);
这里,cls指向6800个零字节数组的开始<代码>((char*)cls)[0]='\0',因此它立即终止,并且不打印任何内容

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值以及其后的任何值,直到它击中一个
0x00
或移动时,它击中一个不属于该进程的地址并导致访问冲突。第一种情况更有可能发生



编辑:显然,另一个答案和讨论的主题被删除了。我将把这个留给未来的访问者。

calloc会用零填充内存。你是如何准确地打印它的?显示你是如何打印指针的
cls
?在你们都参考了我是如何打印它之后,我发现问题就出在这里!多谢各位@mtijanic,你能回答这个问题吗,这样我就可以标记为正确答案?在C中,从calloc()和函数族返回的值不应该被强制转换。@user3629249,如果我不强制转换,从calloc返回的值会是学生结构类型的指针,指向分配的内存吗?