我目前正在学习代码C,但我坚持在堆上创建一个结构。 我有以下代码:
#include <stdio.h>
typedef struct{
int a;
int b;
} some_struct;
int main(int argc, char ** argv) {
printf("%i", sizeof(some_struct));
some_struct * p_struct = malloc(sizeof(some_struct));
p_struct->a = 600;
p_struct->b = 100;
return 0;
}
但是当执行时Visual Studio告诉我:
test.exe中0x00007FF6286C1E39处的未处理异常:0xC0000005:访问冲突写入位置0xFFFFFFFFAFBE4440。
此外,调试器告诉我a和b的内存都无法读取。我知道这两个整数应该是未初始化的,但为什么他们的记忆似乎不可读?
答案 0 :(得分:4)
查看您的地址,看起来malloc()
缺少原型是个问题。做:
#include <stdlib.h>
隐式int
导致malloc()
返回的值被截断(假设64位地址和32位整数)。因此,产生了无效的地址。
在C99之前,如果找不到函数的原型,编译器会隐式声明int
的原型。但是自C99以来这已经不再有效了。
答案 1 :(得分:4)
您应该#include <stdlib.h>
包含malloc
。 Visual Studio不会给你任何警告吗?
当您不包含<stdlib.h>
时,malloc
的隐式返回类型为int
。此可能在sizeof(int) == sizeof(some_struct*)
的平台上工作,但如果它们的大小不同(例如32位整数和64位指针),则malloc
返回的值在分配之前被截断。
错误消息(0xFFFFFFFFAFBE4440
)中的值表明情况如此:malloc
返回了一个值为0x????????AFBE4440
的指针,该指针被截断为0xAFBE4440
,在作业时签名已扩展为0xFFFFFFFFAFBE4440
。
答案 2 :(得分:0)
发生这种情况是因为你调用函数malloc但是你忘了(或者你不知道)包含stdlib.h。
以下是工作代码:
#include <stdio.h>
#include<stdlib.h>
typedef struct{
int a;
int b;
} some_struct;
int main(void) {
printf("%lu", sizeof(some_struct));
some_struct * p_struct = malloc(sizeof(some_struct));
p_struct->a = 600;
p_struct->b = 100;
return 0;
}
你可能已经注意到我改变了:
printf(&#34;%i&#34;,sizeof(some_struct));
使用:
printf(&#34;%lu&#34;,sizeof(some_struct));
如果你打开你的编译器设置,你会得到:
格式'%i'需要类型为'int'的参数,但参数2的类型为'long unsigned int'[-Werror = format =] |
注意: 在这里使用%i而不是%d就可以了,但与scanf不一样。