IT박스

Malloc vs New – 다른 패딩

itboxs 2020. 8. 6. 08:05
반응형

Malloc vs New – 다른 패딩


고성능 컴퓨팅 (10 ^ 5-10 ^ 6 코어)에 MPI를 사용하는 프로젝트의 다른 사람의 C ++ 코드를 검토하고 있습니다. 이 코드는 서로 다른 아키텍처에서 (잠재적으로) 다른 시스템 간의 통신을 허용하기위한 것입니다. 그는 다음과 같은 내용의 설명을 썼습니다.

우리는 일반적으로 newand를 사용 delete하지만 여기서는 mallocand를 사용 하고 free있습니다. 이것은 일부 컴파일러 new가 사용될 데이터를 다르게 채우므로 다른 플랫폼간에 데이터를 전송하는 데 오류가 발생 하기 때문에 필요 합니다. 에서는 발생하지 않습니다 malloc.

이것은 표준 newmalloc질문 에서 내가 아는 것과는 맞지 않습니다 .

신규 / 삭제와 malloc / free의 차이점은 무엇입니까? 컴파일러가 객체의 크기를 다르게 계산할 수 있다는 아이디어를 암시합니다 (그러나 왜 sizeof? 를 사용하는 것과 다른가 ).

malloc & place new와 new 는 상당히 인기있는 질문이지만 관련이없는 new생성자 사용하는 것에 대해서만 이야기 malloc합니다.

malloc은 어떻게 정렬을 이해합니까? 메모리가 제대로 중 하나에 정렬이 보장되는 것을 말한다 new거나 malloc하는 것은 내가 이전에 생각했던 것 것입니다.

내 생각 엔 그가 과거에 자신의 버그 시간을 좀 오진 및 추론 점이다 new그리고 malloc나는 사실이 아니다 아마 생각 패딩 서로 다른 양의를 제공합니다. 그러나 Google이나 이전 질문에서 답을 찾을 수 없습니다.

도와주세요, StackOverflow, 당신은 나의 유일한 희망입니다!


IIRC 까다로운 점이 하나 있습니다. malloc모든 표준 유형에 맞는 주소를 반환합니다. ::operator new(n)n 이하의 모든 표준 유형에 대해 정렬 된 주소 만 반환하도록 보장되며 T문자 유형이 아닌 경우 new T[n]정렬 된 주소 만 반환하면됩니다 T.

그러나 이것은 플래그를 저장하기 위해 포인터의 맨 아래 몇 비트를 사용하거나 엄격하게 필요한 것보다 더 정렬하기 위해 주소에 의존하는 것과 같은 구현 별 트릭을 재생할 때만 관련이 있습니다.

객체 내 패딩에는 영향을 미치지 않으며, 차지하는 메모리를 어떻게 할당했는지에 관계없이 반드시 동일한 레이아웃을 갖습니다. 따라서 차이로 인해 데이터 전송 오류가 발생할 수있는 방법을 찾기는 어렵습니다.

그의 의견에 따르면 "말록처럼 채워지 다"또는 "새로운 것 같이 채워져있다"든, 그 의견의 저자가 스택이나 전역에있는 물체에 대해 어떻게 생각 하는가? 그것은 아이디어가 어디에서 왔는지에 대한 단서를 줄 수 있습니다.

어쩌면 그는 혼란 스럽지만 어쩌면 그가 이야기하는 코드는 malloc(sizeof(Foo) * n)vs과 의 단순한 차이 이상 new Foo[n]입니다. 아마도 더 비슷할 것입니다 :

malloc((sizeof(int) + sizeof(char)) * n);

vs.

struct Foo { int a; char b; }
new Foo[n];

즉, 어쩌면 그가 것입니다 말하는 "나는의 malloc를 사용"하지만, 수단 "나는 수동으로 대신 구조체를 사용하여 정렬되지 않은 위치에 데이터를 팩". 실제로 malloc수동으로 구조체를 포장하는 데 필요하지는 않지만, 혼란의 정도는 적습니다. 와이어를 통해 전송되는 데이터 레이아웃을 정의해야합니다. 구조체 가 사용될 때 다른 구현은 데이터를 다르게 채 웁니다 .


동료가 new[]/delete[]마법의 쿠키를 염두에두고 있었을 수도 있습니다 (배열을 삭제할 때 구현에서 사용하는 정보입니다). 그러나 할당 된 주소 new[]가 아닌 주소에서 시작된 할당 이 사용 된 경우에는 문제가되지 않았을 것 입니다.

포장 이 더 가능성이있는 것 같습니다. (예를 들어) ABI의 변형은 구조의 끝에 추가 된 다른 수의 후행 바이트를 초래할 수 있습니다 (이는 배열에 의해 영향을받습니다. malloc을 사용하면 구조의 위치를 ​​지정할 수 있으므로 외국 ABI에보다 쉽게 ​​이식 할 수 있습니다. 이러한 변형은 일반적으로 이송 구조물의 정렬 및 패킹을 지정함으로써 방지됩니다.


객체의 레이아웃은 사용하여 할당되었는지 여부에 의존 할 수 malloc또는 new. 둘 다 같은 종류의 포인터를 반환하며이 포인터를 다른 함수에 전달하면 객체가 어떻게 할당되었는지 알 수 없습니다. 할당 방법 sizeof *ptr이 아니라의 선언에만 의존합니다 ptr.


그 쪽이 맞는 거 같아요. 패딩은 컴파일러에 의해 수행 new되거나 수행되지 않습니다 malloc. 패딩 고려 사항은 사용하지 않고 배열이나 구조체를 선언에도 적용되는 것 new또는 malloc전혀. 어떤 경우에는 내가 얼마나 다른 구현을 볼 수있는 동안 newmalloc나는 완전히 그들이 문제 플랫폼간에 데이터를 전송 될 수 있습니다 방식을 볼 실패, 플랫폼간에 코드를 포팅 할 때 문제가 발생할 수 있습니다.


MS Visual 컴파일러를 사용하여 평범한 오래된 데이터 구조의 레이아웃을 제어하고 싶을 때 사용 #pragma pack(1)합니다. gcc 와 같은 대부분의 컴파일러에서 이러한 사전 컴파일러 지시문이 지원된다고 가정 합니다.

이는 빈 공간없이 구조의 모든 필드를 서로 뒤에서 정렬 한 결과입니다.

다른 쪽의 플랫폼이 동일한 작업을 수행하는 경우 (즉, 1의 패딩으로 데이터 교환 구조를 컴파일 한 경우) 양쪽에서 검색된 데이터가 적합합니다. 따라서 나는 C ++에서 malloc을 가지고 놀 필요가 없었다.

최악의 경우 C ++에서 malloc을 직접 사용하는 대신 까다로운 작업을 수행하기 위해 새 연산자를 오버로드하는 것을 고려했을 것입니다.


이것은이 일이 어디에서 왔는지에 대한 야생의 추측입니다. 언급했듯이 문제는 MPI를 통한 데이터 전송에 있습니다.

Personally, for my complicated data structures that I want to send/receive over MPI, I always implement serialization/deserialization methods that pack/unpack the whole thing into/from an array of chars. Now, due to padding we know that that size of the structure could be larger than the size of its members and thus one also needs to calculate the unpadded size of the data structure so that we know how many bytes are being sent/received.

For instance if you want to send/receive std::vector<Foo> A over MPI with the said technique, it is wrong to assume the size of resulting array of chars is A.size()*sizeof(Foo) in general. In other words, each class that implements serialize/deserialize methods, should also implement a method that reports the size of the array (or better yet store the array in a container). This might become the reason behind a bug. One way or another, however, that has nothing to do with new vs malloc as pointed out in this thread.


In c++: newkeyword is used to allocate some particular bytes of memory with respect to some data-structure. For example, you have defined some class or structure and you want to allocate memory for its object.

myclass *my = new myclass();

or

int *i = new int(2);

But in all cases you need the defined datatype (class, struct, union, int, char etc...) and only that bytes of memory will be allocated which is required for its object/variable. (ie; multiples of that datatype).

But in case of malloc() method, you can allocate any bytes of memory and you don't need to specify the data type at all times. Here you can observe it in few possibilities of malloc():

void *v = malloc(23);

or

void *x = malloc(sizeof(int) * 23);

or

char *c = (char*)malloc(sizeof(char)*35);

malloc is a type of function and new is a type of data type in c++ in c++, if we use malloc than we must and should use typecast otherwise compiler give you error and if we use new data type for allocation of memory than we no need to typecast

참고URL : https://stackoverflow.com/questions/13286706/malloc-vs-new-different-padding

반응형