- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
好吧,据我所知。我将首先提供上下文。我想将“控件”定义为基本的屏幕小部件:
typedef struct {
struct Control** children;
SDL_Surface* surface;
struct Control* parent;
char* type;
int width;
int height;
int x;
int y;
} Control;
主界面叫做Window,我专门为它做了一个init函数:
Control* createWindow() {
Control window = {
.type = "window",
.surface = SDL_SetVideoMode(WIN_W, WIN_H, 24, SDL_SWSURFACE),
.height = WIN_H,
.width = WIN_W,
.x = 0,
.y = 0
};
return &window;
}
它有一个称为 Panel 的子项,它有自己的初始化程序:
Control* createPanel(const char* filepath, Control* parent, int x, int y, int numberOfChildren) {
Control panel = {
.parent = parent,
.children = (Control**)malloc(numberOfChildren * sizeof(Control*)),
.type = "panel",
.x = x,
.y = y,
.surface = SDL_LoadBMP(filepath)
};
return &panel;
}
以及主函数的开头:
int main(int argc, char* args[]) {
Control* window = NULL;
Control* panel = NULL;
SDL_Init(SDL_INIT_EVERYTHING);
window = createWindow();
panel = createPanel("BACKGROUND.bmp", window, 0, 0, 3);
现在,当到达 createWindow()
函数时,一切都很好,并且 window
已明确定义。在下一行之后,面板初始化,window
被破坏。我只是不明白为什么。
我想这可能是因为我发送了 window
被指定为 panel
的父级,所以我尝试不传递它并删除该分配。不行,在 createPanel()
返回后,它仍然把主作用域中 window
的字段弄乱。
我已经调试了这个问题很长时间了,但我已经没有线索了。我是 C 的新手,可能会发生指针异常,但我不知道,所以我真的希望这是一件完全微不足道的事情..
感谢您的宝贵时间。
最佳答案
为什么不简单:
void createWindow(Control * c) {
*c = {
.type = "window",
.surface = SDL_SetVideoMode(WIN_W, WIN_H, 24, SDL_SWSURFACE),
.height = WIN_H,
.width = WIN_W,
.x = 0,
.y = 0
};
}
然后:
Control c;
createWindow(&c);
这样你在调用位置为对象分配空间并将其地址传递给函数以初始化该地址,这实际上是 RVO 的手动实现,编译器很可能足够聪明并找出指针指向堆栈对象并直接就地初始化数据而不调用函数。
引用堆栈上的内存来使用一个函数已经返回的对象是一个非常糟糕的主意。该数据可能会保留“一段时间”,但当堆栈再次达到该深度时,数据将被覆盖,下次您将获得和/或制造垃圾。您还可以动态分配内存并返回指向它的指针,同时记住在调用位置处理该数据或依赖于其他一些管理方案,但这会有点矫枉过正,因为在您的情况下可以避免很小的开销。
对于您的问题,全局将是一个相当笨拙的解决方案,而且完全没有意义。如果您决定拥有多个窗口,您是否要编辑源代码并重新编译以在每次需要时添加另一个全局窗口?似乎不是个好主意。
编辑:我在发布代码之前没有测试它,假设它可以工作,但指定的初始化器似乎不能与取消引用的指针一起工作。将初始化程序转换为类型的工作方式与您在评论中指出的一样,编译器生成的代码应该与“程序化”初始化相同,即 c->type = "window"
等等是我个人会做的。
关于c - C : A variable changes when it shouldn't 中的 SDL 1.2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26195895/
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我是 .NET 框架开发人员的新手。我刚刚通过 IIS 将我的 Web 部署到 Web 服务器中,但遇到了一些问题。我无法登录,需要显示我的数据库表的菜单没有显示。 Error.An error oc
我是 .NET 框架开发人员的新手。我刚刚通过 IIS 将我的 Web 部署到 Web 服务器中,但遇到了一些问题。我无法登录,需要显示我的数据库表的菜单没有显示。 Error.An error oc
这个问题已经有答案了: When is it OK to catch NullPointerException? (10 个回答) 已关闭 4 年前。 请耐心等待,因为我已经阅读了一些相关内容,但我仍
我读过 When should I use a struct instead of a class?其中引用了 MSDN 的指南,其中说: Do not define a structure unle
在接口(interface)中,我有一个方法可以在一个实现中使用,但不应该在另一个实现中使用。如果有人在那个特定的实现中使用那个方法,我正在考虑抛出一个异常。 (这并不是说很容易意外遇到该异常) 更具
我读了很多关于 TDA 以及 getter 和 setter 方法的优缺点的文章,尽管我不一定同意我读到的所有内容,但假设您应该总是告诉而不是询问,并且您应尽可能避免访问器方法,这是否意味着所有方法都
最近我正在更新一些用于使用 GetWindowDC -> CreateCompatibleDC -> CreateCompatibleBitmap -> SelectObject -> BitBlt
我检查了一些其他问题,显然最好的解决方案是首先防止导致此问题的行为,但问题非常间歇性,而且非常不可重现。 我基本上有一个主窗体和子窗体。子表单显示在主表单的菜单和/或按钮中,如下所示: private
From MSDN : If the most significant bit is set, the key is down, and if the least significant bit is
最近我将我的代码从 Express 更改为 Restify。老实说,我不确定以前是否发生过这种情况,但我想确实发生过。 基本上在我的中间件中,我调用了一个 promisified 方法,当它解析时,我
我在 VB.NET 中使用 LINQ,有时我会遇到类似的查询 For i = 0 To 10 Dim num = (From n In numbers Where n Mod i = 0 Sele
我刚刚升级到 Yarn v1.0.2(稳定版),当我执行 yarn install 时,我收到了很多这样的警告: The case-insensitive file shouldn't be copi
我是一名优秀的程序员,十分优秀!