• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

헤더에 선언한 클래스로 메인함수에서 생성하였을 때 값 전달에 관한 질문

21.01.04 22:03 작성 조회수 256

0

안녕하세요. 
헤더에 선언한 클래스로 메인함수에서 생성하였을 때 값 전달에 관한 질문입니다. 

main 함수에서 header에 있는 클래스 배열을  생성하는데 값이 전달이 안됩니다. 

주소를 확인해 보니 class안에서 작동될 떄의 배열과 main 함수에서 생성한 배열의 메모리 주소가 다릅니다.

헤더에 있는 클래스를 이용하고, main 함수에서 생성자를 사용하여 새로운 2차원 배열을 만들려고 하는데 어떻게 해야 값이 전달되는지 모르겠습니다. 혹시 제가 놓치고 있는 근본적인 실수가 있을까 하여 코드 전문을 첨부합니다. 

바쁘신데 읽어주셔서 정말 감사합니다 :)

//아래로 헤더 
#pragma once
#include <iostream>
using namespace std;

class Matrix
{

private:  
	int** m_arr;
	int m_size = 0;

public:
	Matrix(const int input_size)
	{
		m_size = input_size;
		int** m_arr = new int* [input_size];
		for (int i = 0; i < input_size; i++)
		{
			m_arr[i] = new int[input_size];
		}
		cout << "클래스 안 주소 값 삽입 전 " << m_arr << endl;
		cout << "enter the element " << endl;

		for (int i = 0; i < input_size; i++)
		{
			for (int j = 0; j < input_size; j++)
			{
				m_arr[i][j] = 0;
				cout << m_arr[i][j]<<" " << endl;
			}
		}


	
		for (int i = 0; i < input_size; i++)
		{
			for(int j = 0; j < input_size; j++)
			{
				int temp = 0;
				cin >> temp;
				m_arr[i][j]=temp; 
				cout << "클래스 안 주소 " <<m_arr << endl;
			}
		}

		cout << "생성 완료 " << endl;
	}

	int mul(int** arr1, int** arr2, int input_size)
	{
		int** mul_arr = nullptr;
		mul_arr = new int* [input_size];

		for (int i = 0; i < input_size; i++)
		{
			for (int j = 0; j < input_size; j++)
			{
				for (int k = 0; k < input_size; k++)
				{
					mul_arr[i][j] = arr1[i][k] + arr2[k][j];
				}
			}
		}

		cout << "행렬의 곱 : " << endl;
		for (int i = 0; i < input_size; i++)
		{
			for (int j = 0; j < input_size; j++)
			{
				cout << mul_arr[i][j] << " ";
			}
			cout << endl;
		}
	};

	void mat_print()
	{

		cout << "행렬 출력" << endl;
		for (int i = 0; i < m_size; i++)
		{
			for (int j = 0; j < m_size; j++)
			{
				cout << this->m_arr[i][j] << " ";
			}
			cout << endl;
		}
	}

};

// 아래로 cpp
#include <iostream>
#include "tools.h"

int main()
{
	int size = 0;

	cout << " enter the matirx_A size, n x n " << endl;
	cin >> size;


	//입력 받은 사이즈에 맞추어 행렬 생성 
	Matrix arr_A(size);
	cout << "클래스 밖 주소 " << &arr_A << endl;
	Matrix arr_B(size);

	arr_A.mat_print();

//	Matrix mul(arr_A,arr_B,size_a);



	return 0;
}

답변 1

답변을 작성해보세요.

1

안소님의 프로필

안소

2021.01.05

안녕하세요!

1. '값을 전달한다'는 말씀의 의미가 잘 이해가 되지 않습니다. 어떤 값을 전달하신다는 의미일까요?

2. "주소를 확인해 보니 class안에서 작동될 떄의 배열과 main 함수에서 생성한 배열의 메모리 주소가 다릅니다." 이 말씀은 혹시

cout << "클래스 밖 주소 " << &arr_A << endl; // main 함수 내부
cout << "클래스 안 주소 값 삽입 전 " << m_arr << endl; // Matrix 생성자 내부

위와 같이 작성해주신 내용으로 보아, main 함수 안에서의 &arr_A 와 Matrix 생성자내의 m_arr 값이 다르다는 것을 두고 말씀하신 것이 맞을까요? arr_A 는 Matrix 타입의 "객체"이며 m_arr은 이 arr_A의 이차원 배열(정확히는 이중포인터) 멤버입니다. arr_A는 배열이 아니라 객체입니다. arr_A은 객체고 m_arr은 배열이고 둘은 완전히 별개이기 때문에 주소가 다를 수 밖에 없습니다. 질문자님께서 main함수에서 Matrix 클래스로부터 arr_A 라는 이름의 객체를 만드신 것입니다. m_arr은 이 arr_A의 배열인 멤버이구요!

3. 질문자님께서 질문해주신 내용은 아니지만, 질문자님 코드는 런타임 에러가 발생합니다. 질문자님께서 코드를 실행하셨을 때 아마 행렬 출력이 제대로 이루어지지 않았을 것입니다. 질문자님께서 값이 전달 안된다고 설명을 하신게 이와 관련된 것일 수도 있겠다는 생각이 드네요.

정상적으로 어떠한 에러도 없이 잘 종료가 되면 (코드: 0개) 메세지가 뜨는데 m_arr 행렬의 원소들이 출력되지도 않았고 (코드: -1073....개) 가 콘솔창에 뜬 것을 볼 수 있습니다. 행렬 출력하는 과정에서 런타임 에러가 발생하여 프로그램이 강제 종료 되버렸기 때문입니다.

(덧붙여서 질문자님의 main함수의 Matrix arr_B(size); 부분은 없애고 출력한 것임을 알려드립니다. 설명드리는데 필요 없는 부분이라 뺏어요!)

위와 같이 디버깅을 해보면 행렬을 출력하는 함수에서 m_arr[i][j]에 접근하려고 하니 에러가 발생하신 것을 확인할 수 있어요.

위와같은 에러가 발생한 이유는 질문자님께서 Matrix 생성자 안에서 m_arr을 초기화할 때 int ** m_arr 라고 선언하셨기 때문입니다. 즉, private: 부분에서 선언된 Matrix의 멤버인 m_arr와는 별개로 Matrix 생성자 안에서만 수명을 가지는 동명이인인 m_arr 이라는 새로운 지역 변수를 만들어주신 셈입니다.  int ** 을 붙여주셨기 때문에 새로운 변수 선언이 되어버린거에요. 그래서 Matrix 생성자 안에서 m_arr의 원소들을 초기화해줄 때 Matrix 클래스의 멤버인 m_arr말고, Matrix 생성자 안에서 새롭게 선언된 지역 변수 m_arr을 여태 초기화해주신 셈입니다.  이 지역변수 m_arr 이차원 배열은 Matrix 생성자가 끝나면 없어집니다. Matrix 안에서 선언된 변수니까요! 그래서 결론적으로 진짜 멤버인 m_arr은 아무런 초기화가 한번도 이루어져본적이 없는 빈 이차원 배열로 남아있는 것입니다. 그래서 행렬의 원소들을 출력하려고 할 때 에러가 발생했던 것입니다. 한번도 초기화 되지 않아 원소가 없는 상태인데 m_arr[i][j] 이런식으로 접근하려고 했기 때문이에요.

변수의 수명과 범위에 대해 앞에서 배우셨으니 이해가 가실겁니다. 질문자님께서 생성자 안에서 int ** m_arr 이라고 새롭게 선언해주시고 초기화를 해주셔서 원래 멤버 m_arr와는 이름만 같을 뿐 별개인, 생성자 안에서만 수명을 가지는 동명이인의 m_arr을 새롭게 만들어주신 것이에요. 여태 여기에다 초기화를 하신거구요! 그래서 진짜 m_arr 멤버는 초기화 된적이 없습니다.

이제 생성자 안에서 int ** m_arr가 아닌 int** 떼고 그냥 m_arr 를 초기화 하면 Matrix의 멤버를 초기화 하는게 되니 에러 없이 정상적으로 입력한 1 2 3 4 가 원소값으로 잘 들어간것을 확인할 수 있습니다. 그래서 행렬 출력도 잘 되고 종료된 것을 확인할 수 있네요.  m_size 초기화 하신 것처럼  m_arr도 그냥 m_arr =  이렇게 초기화 하셨어야 했습니다!