Это очень простой вопрос, но он может быть головной болью для новичков, которые об этом не знают. В C++ функция не может напрямую возвращать массив, но массив по сути является указателем, поэтому можно заставить функцию возвращать указатель, чтобы добиться этого. Например, для функции умножения матриц мы можем легко написать:
Пример
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;
}
Но после запуска мы обнаруживаем, что результат такой:
1.75 1.75 6.51468e-039 3.76489e-039
Это не тот результат, который нужен. Поэтому мы добавляем код вывода внутри функции, чтобы проверить, не в вычислении ли проблема, и получаем результат:
1.75 1.75 0 0 1.75 1.75 1.96875 1.75
Мы обнаруживаем, что результат вычисления правильный, но после возврата он меняется и отличается от предыдущего результата. Почему так?
Поскольку массив M, определённый в функции, освобождается системой после завершения выполнения функции, результат, полученный при вызове функции, естественно, не является вычисленным результатом. Одно из решений — динамически выделить память, создав массив внутри функции с помощью new, чтобы он не освобождался.
Значит, нам следует изменить:
float M[4];
на:
float *M = new float[4];
После изменения при запуске получается результат:
1.75 1.75 0 0 1.75 1.75 0 0
Правильно. Однако мы не освободили пространство, которое выделили сами. Если освободить его внутри функции, результат будет таким же, как в самом начале.
Посмотрите на наш код вызова:
float *M = MultMatrix(A, B);
Это фактически указывает указатель M на первый адрес массива M в функции. Мы можем освободить указатель M, и эффект будет таким же, как освобождение выделенного массива M, потому что они указывают на одно и то же пространство памяти. Поэтому код изменён на:
Пример
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;
удаление[] M;
return 0;
}
Результат выполнения:
1.75 1.75 0 0 1.75 1.75 0 0
Не проблема, пространство, выделенное с помощью new, тоже освобождается.
Учитывая приведённые ниже советы экспертов, я изменил программу следующим образом. Все, посмотрите, приемлемо ли это:
Пример
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;
удаление[] M;
return 0;
}
Комментарии по рецензированию:
Во-первых, для массива delete должен быть delete[].
Во-вторых, важный принцип ручного управления памятью в C++ состоит в том, что тот, кто выделяет память, должен её освобождать.
Поэтому не следует использовать new для создания массива внутри MultMatrix; вместо этого его следует выделить снаружи и передать внутрь для изменения.
Чтобы вернуть массив, правильный способ — использовать что-то вроде умных указателей.
Исходный адрес: https://www.cnblogs.com/yangxi/archive/2011/09/18/2180759.html