我试图用从套接字接收的数据填充分配给我的数组,但是无法使其正常工作。当我定义并通过以下方式获取数据时:
uint16_t data[2048];
recv(network_socket, &data, sizeof(data), 0);
可以正确接收数据,但是当我尝试通过分配的数组进行操作时:
int i;
int N = 3;
int M = 2048;
int **matrix;
matrix = (int **)calloc(N, sizeof(int *));
for (i=0; i<N; i++) {
matrix[i] = (int *)calloc(M, sizeof(uint16_t));
}
for (i=0; i<N; i++) {
recv(network_socket, matrix[i], sizeof(data), 0);
}
我感觉到最后出现了问题。据我了解,matrix[i]
的末尾获得指向行i
开头的指针,并且应该为recv()
工作,但这可能是我在这里出错的地方。
编辑:当我尝试printf("Number: %" PRIu16 "\n", matrix[a][b]);
时,在第二部分中会得到一些大字号,printf("Number: %" PRIu16 "\n", data[a]
);首先效果很好。
答案 0 :(得分:3)
您在第一个代码中告诉您要一个16位无符号整数数组并接收它们。一切都很好。
在第二个代码中,您需要一个int
数组,它们可能不是您平台上的16位。然后,根据它们的16位值为它们分配一定数量的内存,并读取未公开的数据量。
然后,您尝试以int
的形式访问它们,这显然会导致将两个uint16_t
值合并为一个int
(如果您的系统是32位,甚至在64位系统上为四个)。
修复代码,使其像第一个一样使用uint16_t
,它实际上会知道如何处理16位数据。由于您尝试访问分配的范围之外的内存,因此您当前的代码甚至将具有未定义的行为。
答案 1 :(得分:2)
评论和其他答案指出了与type
一致性(建议使用int
或uint16_t
而不建议混合使用)和分配内存有关的一些潜在问题。
关于内存创建的建议:
为了简化和提高可读性,尤其是在希望模拟数组的多个维度时,请考虑将内存创建封装到一个函数中。例如:
uint16_t ** Create2D(int c, int r)
{
uint16_t **arr;
int y;
arr = calloc(c, sizeof(uint16_t *));
for(y=0;y<c;y++)
{
arr[y] = calloc(r, sizeof(uint16_t));
}
return arr;
}
这样调用函数:
uint16_t ** matrix = Create2D(N, M);
if(matrix)//always good to check return of [c][m]alloc before using
{
// Use allocated memory
...
注意:
uint16_t array[N][M];
malloc
or calloc
。[m][c]alloc()
,都必须有一个相应的呼叫
到free()
。释放此内存也可以以封装形式实现。例如:
void free2D(uint16_t **arr, int c)
{
int i;
for(i=0;i<c;i++)
{
free(arr[i]);
}
free(arr);
}
答案 2 :(得分:1)
int **matrix;
matrix = (int **)calloc(N, sizeof(int *));
...
由于上面的代码不是2D数组,而是分段的,基于指针的查找表,因此代码不起作用。因此,它与数组一点也不兼容。
没有理由在这里需要这样的查找表。问题可能源于对如何Correctly allocating multi-dimensional arrays的困惑。