问题背景:
某函数如果想要输出多个数据的时候,通常我会想到用指针传参,然后利用指针修改指针指向的空间的内容,从而突破函数只有一个返回值的限制,例如:
int myFunc(int inNum1, int inNum2, int* outNum1, int* outNum2){
if(outNum1 == NULL || outNum2 == NULL)
return -1;
*outNum1 = inNum1+inNum2;
*outNum2 = inNum1-inNum2;
return 0;
}
上面函数的功能是提供两个整数,并存在两个输出,输出1的结果是输入的两个整数的和,另一个是差。 函数外部的使用方法是:
- int err = 0;
- int a = 0,b = 0;
- err = myFunc(1,2,&a,&b);
但是我发现当处理数组型的输出时,这个方法会出问题,例如:
int myDotf2(float* inArr1, int x1, int y1, float* inArr2, int x2, int y2, float* outArr, int *outX, int *outY) {
int arrType_inArr1[2] = { x1,y1 };
int posIndex_inArr1[2] = { 0 };
int arrType_inArr2[2] = { x2,y2 };
int posIndex_inArr2[2] = { 0 };
int arrType_outArr[2] = { 0 };
int posIndex_outArr[2] = { 0 };
if (y1 != x2) {
printf("矩阵1和2的行列长度不合法\n");
return -1;
}
*outX = x1;
*outY = y2;
if(outArr != NULL){
free(outArr);
}
outArr = (float*)malloc(sizeof(float) * (*outX) * (*outY));
if (outArr == NULL)
return -2;
memset(outArr,0, sizeof(float) * (*outX) * (*outY));
arrType_outArr[0] = *outX; arrType_outArr[1] = *outY;
//计算
for (int i = 0; i < x1; i++) {
for (int j = 0; j < y2; j++) {
posIndex_outArr[0] = i; posIndex_outArr[1] = j;
for (int k = 0;k< y1; k++) {
posIndex_inArr1[0] = i; posIndex_inArr1[1] = k;
posIndex_inArr2[0] = k; posIndex_inArr2[1] = j;
outArr[getIndexOfArr(arrType_outArr,2, posIndex_outArr)] += inArr1[getIndexOfArr(arrType_inArr1, 2, posIndex_inArr1)] * inArr2[getIndexOfArr(arrType_inArr2, 2, posIndex_inArr2)];
//outArr[i][j] += inArr1[j][k]*inArr2[k][j];
}
}
}
return 0;
}
上面的函数是在做一个二维矩阵乘法函数,请忽略内部奇怪的索引表示法,在此不细说,有兴趣可见另一篇文章。 这个函数存在多个输入和多个输出,输入包括不定长二维矩阵inArr1和不定长二维矩阵inArr2,以及他们的各维度长度。输出包括一个二维矩阵及它的各维度长度,也就是三个输出。 按照最初的想法,传入的是一个数组头,也就是一个指针变量,我在函数内部为他malloc一段内存,并进行计算赋值,且不free,按我的想法它应该不会被释放,且因操作的是指针(也就是内存地址),所以应该能正常修改值,和一般的int型指针同理。但是事实并非如此。
问题现象:
问题的现象是我在外部传入的对应指针一直是NULL,或者说我在外边怎么初始化的,该函数执行结束后,它还是什么样,不变,也就是函数并没有给它成功的赋值。相反,另两个int型的输出被正确的赋值了。
解决方法:
将数组类型的输出由指针参数的形式换成返回值形式,问题得以解决。如下:
float* myDotf2(float* inArr1, int x1, int y1, float* inArr2, int x2, int y2, int *outX, int *outY) {
int arrType_inArr1[2] = { x1,y1 };
int posIndex_inArr1[2] = { 0 };
int arrType_inArr2[2] = { x2,y2 };
int posIndex_inArr2[2] = { 0 };
int arrType_outArr[2] = { 0 };
int posIndex_outArr[2] = { 0 };
float* outArr = NULL;
if (y1 != x2) {
printf("矩阵1和2的行列长度不合法\n");
return NULL;
}
*outX = x1;
*outY = y2;
outArr = (float*)malloc(sizeof(float) * (*outX) * (*outY));
if (outArr == NULL)
return NULL;
memset(outArr,0, sizeof(float) * (*outX) * (*outY));
arrType_outArr[0] = *outX; arrType_outArr[1] = *outY;
//计算
for (int i = 0; i < x1; i++) {
for (int j = 0; j < y2; j++) {
posIndex_outArr[0] = i; posIndex_outArr[1] = j;
for (int k = 0;k< y1; k++) {
posIndex_inArr1[0] = i; posIndex_inArr1[1] = k;
posIndex_inArr2[0] = k; posIndex_inArr2[1] = j;
outArr[getIndexOfArr(arrType_outArr,2, posIndex_outArr)] += inArr1[getIndexOfArr(arrType_inArr1, 2, posIndex_inArr1)] * inArr2[getIndexOfArr(arrType_inArr2, 2, posIndex_inArr2)];
//outArr[i][j] += inArr1[j][k]*inArr2[k][j];
}
}
}
return outArr;
}