我正在线上获取操作系统类,我完成了第一个分区http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-828-operating-system-engineering-fall-2012/assignments/MIT6_828F12_assignment1.pdf但是让我感到惊讶的是他们如何返回数据结构,他们使用数据结构并返回较小的数据结构,并使用它,他们只是将其转换回来。我看到它可以优化代码,但这样安全吗?这是好习惯吗?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct small
{
int n ;
};
struct big
{
int n ;
char * string ;
};
struct small* f()
{
struct big* x = malloc(sizeof(struct big));
x->n = 'X';
x->string = strdup("Nasty!");
return (struct small*) x ;
}
int main(int argc, char *argv[])
{
struct big *y = (struct big*)f();
printf("%s\n",y->string);
}
编辑1:这是来自mit的链接,我只是在我自己的代码中复制了这个想法。 http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-828-operating-system-engineering-fall-2012/assignments/sh.c
答案 0 :(得分:5)
没有返回结构,但是指针返回到结构。指针包含实际对象所在的内存地址。 (在这种情况下,它已使用malloc
动态分配,因此具有动态存储持续时间,并将一直存在直到指针结束或指针上调用free
。)
代码合法且定义了语义。 n1570草案的6.3.2.3/7说
指向对象类型的指针可以转换为指向a的指针 不同的对象类型。如果结果指针不正确 对于引用的类型,行为是未定义的。 [此处不适用。 -PS] 否则,当再次转换回来时,结果应该相等 到原始指针。
请注意,结构可能完全不相关(第一个数据元素不需要是同一类型)。演员阵容甚至可以是int
等内置类型。
如果由于别名问题而通过错误类型的指针(它不是访问,则问题可能会有所不同。
答案 1 :(得分:1)
是的,只要您的编译器遵循C标准
,它就是安全的Why doesn't GCC optimize structs?
但不,我认为这不是一个好习惯。
良好做法是相对的,绝不应该作为规则使用。如果要使用C来模拟OO继承行为,则需要此构造。
答案 2 :(得分:1)
回答你的问题:
安全吗?
显然不是。只需将指针类型转换为其他东西,只有在您确定它是正确的类型时才应该这样做。
但是,如果你知道,一切都很好。
这是好的做法吗?
不,不是这种形状。
您有时会以类似的方式在C中进行面向对象编程(比较CPython&#39; s struct obj_type {
const char* name;
size_t length; // this is important so that you can copy the object later on without knowing its insides
};
struct obj_base {
obj_type* type;
};
):您使用一个&#34; base&#34;对象和一个&#34;类型&#34; struct具有如下结构:
struct more_complex_object {
obj_type* type;
int value;
};
...
int main() {
obj_type *more_complex_object_type = malloc(sizeof(obj_type));
more_complex_object_type->name = "A more complex object type";
more_complex_object_type->length = sizeof(more_complex_object);
more_complex_object *obj = malloc(more_complex_object_type->length);
obj->type = more_complex_object_type;
obj->value = 10;
...
//let's now use it as a simple instance of the "super" object
obj_base* just_an_object = (obj_base*)more_complex_object;
//when we copy things, we make sure to copy the full length:
obj_base* target = malloc(sizeof(more_complex_object));
memcpy(target, just_an_object, just_an_object->type->length);
//now, when handling an object, we can check its type
if(just_an_object->type == more_complex_object_type) {
more_complex_object *my_obj = (more_complex_object)just_an_object;
printf("value: %d\n", my_obj->value);
}
}
因为可以保证在C中,指向结构的指针指向它们的第一个元素的地址,所以你可以使用构建在其上面的其他对象:
<LayoutTemplate>
<table id="TimeSheet">
<thead>
<tr>
<th id="thDelete" runat="server" Visible='<%# If( IsAdmin().tostring()="True", "true", "false") %>'>
Select
</th>
</tr>
</thead>
<tbody>
<tr id="itemPlaceholder" runat="server" />
</tbody>
</table>
</LayoutTemplate>`