Este problema es de nivel muy básico, pero para quienes recién empiezan y no lo saben, puede resultar bastante frustrante. En C++, una función no puede devolver directamente un array, pero como un array en realidad es un puntero, podemos hacer que la función devuelva un puntero para lograrlo. Por ejemplo, en una función de multiplicación de matrices, fácilmente la escribiríamos así:
Ejemplo
using namespace std;
float* MultMatrix(float A[4], float B[4])
{
float M[4];
M[0] = A[0]*B[0] + A[1]*B[2];
M[1] = A[0]*B[1] + A[1]*B[3];
M[2] = A[2]*B[0] + A[3]*B[2];
M[3] = A[2]*B[1] + A[3]*B[3];
return M;
}
int main()
{
float A[4] = { 1.75, 0.66, 0, 1.75 };
float B[4] = {1, 1, 0, 0};
float *M = MultMatrix(A, B);
cout << M[0] << " " << M[1] << endl;
cout << M[2] << " " << M[3] << endl;
return 0;
}
Pero al ejecutarlo, descubrimos que el resultado es:
1.75 1.75 6.51468e-039 3.76489e-039
No es el resultado que queríamos. Entonces añadimos código de visualización dentro de la función para ver si es un problema de cálculo, y obtenemos el resultado:
1.75 1.75 0 0 1.75 1.75 1.96875 1.75
Descubrimos que el resultado del cálculo es correcto, pero cambia después de devolverse, y además es diferente del resultado anterior. ¿Por qué ocurre esto?
Porque el array M definido dentro de la función ya ha sido liberado por el sistema cuando la función termina de ejecutarse, por lo que el resultado obtenido al llamar a la función, por supuesto, no es el resultado después del cálculo. Una solución es asignar memoria dinámicamente: usar `new` para crear un array dentro de la función, de modo que no sea liberado.
Entonces deberíamos cambiar:
float M[4];
Por:
float *M = new float[4];
Después de la modificación y ejecución, obtenemos el resultado:
1.75 1.75 0 0 1.75 1.75 0 0
Correcto. Pero de esta manera no hemos liberado el espacio que nosotros mismos solicitamos; si lo liberamos dentro de la función, el resultado será igual que al principio.
Veamos nuestro código de llamada:
float *M = MultMatrix(A, B);
Esto en realidad hace que el puntero M apunte a la dirección inicial del array M dentro de la función. Podemos liberar el puntero M, y el efecto es el mismo que liberar el array M solicitado, porque apuntan a la misma región de memoria. Entonces el código se modifica a:
Ejemplo
using namespace std;
float* MultMatrix(float A[4], float B[4])
{
float *M = new float[4];
M[0] = A[0]*B[0] + A[1]*B[2];
M[1] = A[0]*B[1] + A[1]*B[3];
M[2] = A[2]*B[0] + A[3]*B[2];
M[3] = A[2]*B[1] + A[3]*B[3];
cout << M[0] << " " << M[1] << endl;
cout << M[2] << " " << M[3] << endl;
return M;
}
int main()
{
float A[4] = { 1.75, 0.66, 0, 1.75 };
float B[4] = {1, 1, 0, 0};
float *M = MultMatrix(A, B);
cout << M[0] << " " << M[1] << endl;
cout << M[2] << " " << M[3] << endl;
delete[] M;
return 0;
}
Resultado de la ejecución:
1.75 1.75 0 0 1.75 1.75 0 0
Sin problemas, el espacio de `new` también se ha eliminado con `delete`.
En vista de las sugerencias de los expertos a continuación, he modificado el programa de la siguiente manera. ¿Creen que está bien?
Ejemplo
using namespace std;
void MultMatrix(float M[4], float A[4], float B[4])
{
M[0] = A[0]*B[0] + A[1]*B[2];
M[1] = A[0]*B[1] + A[1]*B[3];
M[2] = A[2]*B[0] + A[3]*B[2];
M[3] = A[2]*B[1] + A[3]*B[3];
cout << M[0] << " " << M[1] << endl;
cout << M[2] << " " << M[3] << endl;
}
int main()
{
float A[4] = { 1.75, 0.66, 0, 1.75 };
float B[4] = {1, 1, 0, 0};
float *M = new float[4];
MultMatrix(M, A, B);
cout << M[0] << " " << M[1] << endl;
cout << M[2] << " " << M[3] << endl;
delete[] M;
return 0;
}
Contenido de los comentarios:
En primer lugar, el `delete` de un array debe ser `delete[]`.
En segundo lugar, un principio importante de la asignación manual de memoria en C++ es: quien asigna, libera.
Por lo tanto, no se debe hacer `new` del array dentro de MultMatrix, sino que se debe crear fuera con `new` y pasarlo a la función para modificarlo.
Si se quiere devolver un array, usar punteros inteligentes o algo similar es el camino correcto.
Dirección original: https://www.cnblogs.com/yangxi/archive/2011/09/18/2180759.html