- 主题:请教两个二级指针的问题
没仔细看代码
我想说的是另外一个角度:
二维动态数组,也是可以用一维的数组来实现的,不需要进行二次的内存分配。
也就是分配一段内存,直接在逻辑视图上视为二维数组(视为三维、N维也是一样的)。
const int M = 3;
const int N = 5;
int* p = (int*)malloc(sizeof(int) * M * N);
for (int i = 0; i < (M * N); ++i) p[i] = i;
int(*a)[M][N] = (int(*)[M][N])p;
for (int row = 0; row < M; ++row) {
for (int col = 0; col < N; ++col) {
printf("%d ", (*a)[row][col]);
}
printf("\n");
}
free(p);
--
FROM 221.218.160.*
一、你这个代码其实是有内存泄漏的
下面这种“遇到失败就返回”的模式称为early return。
if (xxx == NULL) {
return;
}
在每个early return之前,是需要释放掉前面所分配的任何内存(或者资源)的。
Mat_tra()里的第二个early return以及更后面的return,没有释放掉前面那个calloc()分配的内存。
另外就是整个代码里没有free()语句
实际上,我推荐直接学C++,而不是C,这些资源问题C++里用RAII都轻松搞定。当然,最重要的是要有资源的分配、释放要配对的意识。但用C是很容易在early return时漏写资源释放语句的。
二、
Mat_tra()这种简写命名,不推荐。因为过一阵你自己可能也未必能记住是什么的简写了,更别说别人了
三、学会使用clang-format格式化代码。顺带看一下clang-format里google style、llvm style里的变量和函数是怎么的命名风格,不要使用很多纯大写的变量名字。
【 在 sqsl 的大作中提到: 】
: 我写了一段计算矩阵的转置矩阵的程序,运行虽然没有报错,但是我觉得我程序里是不是有两个错误?
: (1)验证了if( AT == NULL )之后,没必要再验证if( AT[i] == NULL )吧?属于多此一举;
: (2)定义**XT后缺少生成2行5列的全零矩阵的步骤。程序这次虽然没有出错,但容易出现内存地址被占用的情况?
: ...................
--
修改:z16166 FROM 221.218.160.*
FROM 221.218.160.*
你得把你输给chatgpt的指令列出来,那个更重要
【 在 forex 的大作中提到: 】
: Chatgpt校正版:
: #include <stdlib.h>
: #include <stdio.h>
: ...................
--
FROM 221.218.160.*
那你还是用C吧,哈
【 在 sqsl 的大作中提到: 】
: 好的,收到
: 我学c的目的是想学嵌入式系统,好像嵌入式用C的人更多一些?
:
--
FROM 221.218.160.*
然后chagpt把我在9楼说的那些全都改了

【 在 forex 的大作中提到: 】
: Can you optimize my code?
: 然后附上楼主的代码 :)
:
--
FROM 221.218.160.*
这种不能用,前面两个下划线的。
用clang-format能支持的风格是最好的,先用它内置的那几种风格里的一种,然后玩熟了再自定义。
https://clang.llvm.org/docs/ClangFormatStyleOptions.html
好处是工具能自动帮你校正书写风格,IDE里也支持clang-format,自己用命令行或者.clang-format配置文件也行。
或者用linux kernel的代码风格,kernel源码根目录下有配置好的.clang-format
【 在 sqsl 的大作中提到: 】
: 去打开头文件看了一眼
: 确实都是按你说的写的:
: __mingw_ovr
: ...................
--
FROM 221.218.160.*
C应该不能
C++可以,用引用就行
int (*a)[M][N] = (int (*)[M][N])p;
const auto &b = *a;
printf("%d\n", b[1][3]);
另外就是这种要求M、N是编译期的常量。运行期M、N可变的话就不行了
得用p[row * M + col]这种去访问了
【 在 paramita555 的大作中提到: 】
:
: int(*a)[M][N] = (int(*)[M][N])p;
--
FROM 221.218.160.*
对
可以打出来类型。下面这个b2类型不一样。b和b3一样。
const auto& b = *a;
const auto& t = typeid(decltype(b));
printf("%s, %s\n", t.name(), t.raw_name());
const auto b2 = *a;
const auto& t2 = typeid(decltype(b2));
printf("%s, %s\n", t2.name(), t2.raw_name());
const int(&b3)[M][N] = *a;
const auto& t3 = typeid(decltype(b3));
printf("%s, %s\n", t3.name(), t3.raw_name());
【 在 paramita555 的大作中提到: 】
:
: C++可以,用引用就行
: int (*a)[M][N] = (int (*)[M][N])p;
: ...................
--
FROM 221.218.160.*
TLV接收端也需要限制长度,不然随便发一个超大的L,接收端就DoS了
【 在 ylh0315 的大作中提到: 】
: 对,就是TLV方法,Type,length ,vector。
: t,l组成固定长度的包头。T就是调用号,在函数数组的下标。服务器返回时用于标识订阅信息。
: 实际上我用了9个整数做包头,36字节。
: ...................
--
FROM 221.218.160.*
长度给发一个几个G的过来,耗掉服务器的资源,哈哈
发送者只需要发一个包头就行了,而服务端为此要malloc几个G的内存
【 在 ylh0315 的大作中提到: 】
: 发过100M的,malloc呗。
: 先收包头,再根据length,太大的就malloc。
: 麻烦的是,什么时候free。等用户用完才能free。
--
FROM 221.218.160.*