realloc로 메모리를 할당할 수가 없습니다.

dltkddyd의 이미지

다음과 같은 코드에서 realloc 함수로 메모리를 할당하려 했지만 컴파일시 invalid pointer라는 메시지가 뜹니다.

#include <iostream>
using namespace std;
#include <cstdlib>
int main() {
	int* ptr1=new int[3];
	int* ptr2=&ptr1[3];
	ptr2=(int*)realloc(ptr2, sizeof(int)*2 );//여기서 컴파일 오류가 발생합니다.
 
	return 0;
}

반드시 &ptr1[3]이라는 위치에 메모리를 할당하려 합니다. ptr2로 그 위치를 저장해서 말이죠. 저런 식으로 사용해야할 이유가 있어서 그런데요. 저 위치에 메모리를 할당하거나 할당 실패시의 상황을 알 수 있는 방법이 없을까요?

jick의 이미지

정확히 뭐를 하시려는지는 잘 모르겠지만 realloc은 malloc으로 받은 포인터에만 적용할 수 있습니다.

시스템에 따라 new로 받은 포인터에 적용할 수 있는 경우도 있다고는 하는데, 된다 하더라도 표준이 아닙니다. 그리고 그런 경우라도 malloc이나 new로 받는 포인터 값에만 (즉 할당 영역의 시작주소) 적용이 되는 것이지 할당 영역에 임의 오프셋을 더해서 아무 주소를 realloc한다는 얘기는 들어본 적이 없습니다. 일단 realloc이 도대체 뭘 해야 되는지 의도 자체가 정의가 안되는데요...

klara의 이미지

jick님 말씀대로 realloc은 malloc에 대응되는 함수니까 일단 실행자체가 보장되지 않습니다.
그리고 realloc은 그자리에 다시 할당하는 것도 아니고 그냥 free/malloc을 하나로 합쳐놨을 뿐이기 때문에 설령 이 코드가 적법하다고 해도 realloc할때마다 반환되는 주소가 같다는 보장은 전혀 없습니다.
마지막으로 주소를 지정해서 할당할 수있는 표준 라이브러리 함수는 존재하지 않습니다.

dltkddyd의 이미지

또 질문이 있습니다. 그렇다면 new로 메모리를 할당하는 것과 malloc로 메모리를 할당하는 것의 차이가 있을까요? 그리고 malloc로 할당한 메모리를 delete로 해제하는 것이 가능한가요? 가령 포인터로 연속적으로 이루어진 객체의 경우에

객체 안 객체 안 객체 안
포인터---> 포인터--> 포인터

그러니까 위와 같은 식으로 연결된 구조의 데이터에 있어서 포인터를 delete로 해제할 경우와 free로 해제할 경우 어떤 차이가 있을까요? new로 저렇게 연결된 객체의 사슬에서 delete로 제일 앞의 포인터를 해제할 경우 모든 객체는 소멸되는 것으로 아는데요? 제일 앞 겍체의 소멸자에서 free로 제일 앞의 포인터를 해제할 경우에도 모든 객체가 파괴될까요?

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

klara의 이미지

new/delete를 malloc/free와 섞어서 쓸수는 없습니다. 구체적으로 어떻게 다르냐는건 컴파일러 구현에 따라 다르지만, 가장 중요한 차이점은 new/delete는 생성자/소멸자를 호출해주지만 malloc/free는 생성자와 소멸자를 호출하지 않는다는 것입니다.

>> new로 저렇게 연결된 객체의 사슬에서 delete로 제일 앞의 포인터를 해제할 경우 모든 객체는 소멸되는 것으로 아는데요?
아닙니다. 그런일은 new/delete가 자동으로 해주지 않습니다. 해준다면 그건 소멸자가 해준거겠죠.
new와 delete의 호출수는 무조건 1대1로 같아야 모든 메모리가 해제됩니다. 여러번 할당하고 한번에 해제한다는 건 불가능합니다.

dltkddyd의 이미지

연속으로 소멸되는지 질문드린 것은 이런 의미에서였습니다.
첫 번째 객체가 소멸되면, 소멸자가 호출될 것이고 그러면

delete 포인터

로 그 옆의 객체가 파괴됩니다. 그러면 다시 소멸자가 호출되고

delete 포인터

로 그 옆의 객체가 파괴됩니다.

그러면 다시 그 옆의 객체가 파괴되고, 다시 소멸자가 호출되어 마지막의 포인터가 가리키는 객체가 소멸된다는 점에서

delete 제일 앞 포인터로 인해 연속으로 메모리가 해제되는 것이죠?

단 소멸자에 delete 포인터가 언급되어 있다고 가정한다면요. xylosper님께서 말씀하신 것도 그런 뜻이죠?

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

klara의 이미지

네 맞습니다.

mirheekl의 이미지

저렇게 할당한 뒤에 어떤 식으로 사용을 하게 되는지..

코드 자체는 메모리 할당 부분을 new대신 malloc으로 바꾸고, 배열을 직접 사용하는게 아니고 포인터 배열을 사용한뒤 배열 내부의 각각의 int 포인터들을 일일이 따로따로 malloc하게 바꾸면 정상적으로 동작을 하겠습니다만 (물론 나중에 메모리 반납도 일일이 다 해줘야겠지요), 객체 사이즈의 유연한 변화가 필요한 경우라면 그냥 STL등에서 제공하는 컨테이너를 쓰시는게 좋을 듯 합니다. 통신이나 저장이 필요하면 그때 별도의 방법으로 직렬화를 하는 게 일반적입니다.

--

익명 사용자의 이미지

realloc() 함수는 입력받은 포인트에 존재하는 메모리를 조정하는 역활을 합니다.
즉 첫번째 매개변수로 malloc()등으로 할당받은 포인트가 들어와야 합니다.
또한 realloc() 호출시 메모리가 부족할 경우 별도의 다른 위치에 메모리가 할당 되며 데이터가 복사 됩니다.

c = realloc(a, b)에서 c는 a일 수도 아닐 수도 있습니다.
물론 c에 할당받은 메모리에는 a에 들어있던 데이터가 그대로 들어 있습니다.
다시 언급하자면 첫번째 매개변수는 메모리를 할당할때 쓰고자 하는 위치가 아닙니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.