c - 返回一个大变量与使用参数中提供的指针设置它
问题描述
我对设置或返回 C 函数内部生成的大型结构时常见的做法很感兴趣。最好和最安全的方法是什么。我可以想出 3 种返回生成结构的方式。他们是否都在记忆方面执行相同的操作,还是一个比另一个更有效?覆盖现有值时情况会发生变化吗?例如,当更改指针时,旧的关联值是否会自动被垃圾收集。
// Returning the instance
Image new_Image(const int height, const int width, const int depth) {
Image out;
out.width = width;
out.height = height;
out.depth = depth;
out.pixels = (float*) calloc((height*width*depth), sizeof(float));
return out;
}
Image image = new_Image(100,100,3);
// OR return a new pointer.
Image *new_Image(const int height, const int width, const int depth) {
Image out;
out.width = width;
out.height = height;
out.depth = depth;
out.pixels = (float*) calloc((height*width*depth), sizeof(float));
return &out;
}
Image *image;
image = new_Image(100,100,3);
// OR init outside function and populate in function. For cleanliness though I'd like as much of the image generating part to be done in the function.
Image *new_Image(Image *out, const int height, const int width, const int depth) {
out.width = width;
out.height = height;
out.depth = depth;
out.pixels = (float*) calloc((height*width*depth), sizeof(float));
}
Image *image = (Image*) malloc(sizeof(Image));
new_Image(image, 100,100,3);
解决方案
Image new_Image(const int height, const int width, const int depth)
安全,但您通过值返回整个结构 - 这不是很有效,大多数实现将通过堆栈来完成。堆栈尤其是在小型嵌入式系统上的大小非常有限。对递归也不友好(每次函数调用都会消耗大量堆栈)
Image *new_Image(const int height, const int width, const int depth) { Image out;
- 当您返回指向局部变量的指针时未定义的行为,当您离开函数时该变量停止存在。Image *new_Image(Image *out, const int height, const int width, const int depth)
如果您使用在函数外部定义或分配的对象是安全的。顺便说一句,您忘记返回指针。您在问题中未提及的选项:
Image *new_Image(const int height, const int width, const int depth) {
Image *out = malloc(sizeof(*out));
/* malloc result tests */
out -> width = width;
out -> height = height;
out -> depth = depth;
out -> pixels = calloc((height*width*depth), sizeof(float));
/* calloc result tests */
return out;
}
你不测试你的内存分配结果。它必须完成。
这个函数也是错误的:
Image *new_Image(Image *out, const int height, const int width, const int depth) {
out.width = width;
out.height = height;
out.depth = depth;
out.pixels = (float*) calloc((height*width*depth), sizeof(float));
}
它应该是:
Image *new_Image(Image *out, const int height, const int width, const int depth) {
out -> width = width;
out -> height = height;
out -> depth = depth;
out -> pixels = calloc((height*width*depth), sizeof(float));
return out;
}
您不需要转换 malloc 系列函数的结果。它被认为是危险的,因为如果您忘记包含 . 语言,您将不会收到任何警告消息。现在,如果您在没有原型的情况下调用函数,编译器会发出警告
如果您使用 C++ 编译器编译代码,请使用命令行选项,这将告诉编译器代码是 C(例如 gcc 或 g++ -xc 选项)
推荐阅读
- ruby-on-rails - Rails + GraphQl + Rspec
- ruby-on-rails - Kubernetes readinessProbe 返回“连接拒绝”
- python - 如何将文件文件夹移动到可变名称文件夹
- sql - 在 AWS Athena 中减去两个时间戳列
- node.js - 用一个后端 Nodejs 运行两个源前端 Reactjs
- asp.net-core - 使用当前版本的 System.Text.Json.JsonSerializer 序列化 DataSet
- php - laravel 使用 ajax 重定向
- ios - 带有 Parse 平台的 iOS 推送通知 - didRegisterForRemoteNotificationsWithDeviceToken - 从未调用
- java - 使用存储过程从输入 csv 文件将多个表创建到 oracle 数据库中
- javascript - 如何存储每个 Http 请求的变量