Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用未定义的指针分配内存_C - Fatal编程技术网

C 使用未定义的指针分配内存

C 使用未定义的指针分配内存,c,C,当gcc-Wall在没有任何警告的情况下编译这篇文章时,我感到惊讶。这真的合法吗?这样编写代码有什么风险 #include <stdio.h> #include <stdlib.h> typedef struct { int a; int b; } MyStruct; int main(void) { MyStruct *s = malloc(sizeof(*s)); // as opposed to malloc(sizeof(MyStruct))

gcc-Wall
在没有任何警告的情况下编译这篇文章时,我感到惊讶。这真的合法吗?这样编写代码有什么风险

#include <stdio.h>
#include <stdlib.h>

typedef struct {
  int a;
  int b;
} MyStruct;

int main(void) {
  MyStruct *s = malloc(sizeof(*s)); // as opposed to malloc(sizeof(MyStruct))
  s->a = 5;
  printf("%d\n", s->a);
}
#包括
#包括
类型定义结构{
INTA;
int b;
}我的结构;
内部主(空){
MyStruct*s=malloc(sizeof(*s));//与malloc(sizeof(MyStruct))相反
s->a=5;
printf(“%d\n”,s->a);
}

它不仅是合法的,甚至比其他选择更可取。这样,编译器就可以推断出实际的类型,而不是手动操作。

sizeof
在编译时进行计算。在此上下文中,
*s
解析为
*s
的类型,它不会取消对指针的引用

这是使用
sizeof
的标准方法。如果使用了
sizeof(int)
,则在类型更改时会留下一个错误的空白(在这种情况下,可能不太可能,但仍然如此)。

MyStruct *s = malloc(sizeof(*s));
具有完全相同的效果

MyStruct *s = malloc(sizeof(MyStruct));
只是现在你只写了一次我的短信。也就是说,您正在分配的对象的源类型是自动确定的,这减少了出错的机会

例如,这发生在我身上,你从一个
MyStruct
开始。然后您决定您还需要一个不同的
MyStruct
,用于不同的目的。因此,您将得到两种不同的结构,
MyStruct
AnotherStruct

然后重构代码,将一些变量从
MyStruct
更改为
AnotherStruct
,最后得到

AnotherStruct *s = malloc(sizeof(MyStruct));
这可能在几种情况下,或者在很长一段时间内有效,直到你在这两种结构中做了另一个小的、完全无关的改变。在这一点上,您的代码将发出咔嗒声

例如


建议这样做,以便显式强制转换。是的,它是有效的,并且是推荐的。@Antoh这不是关于强制转换@Deduplicator的结果可能的副本否,它不需要注意给定:
void function(const char*n){short a[atoi(n)];size_t s=sizeof(a)/sizeof(a[0]);使用a和s的代码。}
sizeof(a)的值
是一个运行时计算,因为
a
是一个可变长度数组。(请注意,
sizeof(a[0])
仍然是一个编译时计算。)除了这个狭隘的教学目的之外,我对代码的质量没有任何要求(这很糟糕)。@JonathanLeffler:没错,VLA的是个例外。
typedef struct {
        int a;
        int b;
} StructA;

typedef struct {
        int a;
        int b;
        int c;
} StructB;

int main() {
        // No problem here except wasted space
        StructA *s = malloc(sizeof(StructB));

        // t->c dwells in undefined country
        StructB *t = malloc(sizeof(StructA));
}