【问题标题】:Initialize struct array with zero value for all用零值初始化结构数组
【发布时间】:2015-05-12 16:30:57
【问题描述】:

我需要初始化我的结构数组,全部为零

我的结构:

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] 我会得到垃圾值;

【问题讨论】:

  • calloc 确实用零填充内存。你是怎么打印出来的?
  • 显示如何打印指针cls?
  • 在你们都参考了我的打印方式之后,我发现问题出在这!非常感谢你。 @mtijanic,您能回答一下,以便我标记为正确答案吗?
  • 在 C 中,calloc() 的返回值和函数族不应强制转换。
  • @user3629249,如果我不强制转换,从 calloc 返回的值是否会是 Student 结构类型的指针,指向分配的内存?

标签: c arrays struct


【解决方案1】:

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

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));
}

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

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

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

请注意,一些编译器可以检查 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或移动命中不属于该进程的地址并导致访问冲突。第一种情况的可能性更大。


编辑:显然,另一个答案和讨论的线程已被删除。我会留在这里给以后的访客。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    • 2021-10-07
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多