C / C ++에서 배열을 복사하는 기능이 있습니까?


91

저는 C / C ++를 배우는 Java 프로그래머입니다. 그래서 Java에는 System.arraycopy ();와 같은 기능이 있다는 것을 알고 있습니다. 배열을 복사합니다. 배열을 복사하는 함수가 C 또는 C ++에 있는지 궁금합니다. for 루프, 포인터 등을 사용하여 배열을 복사하는 구현 만 찾을 수있었습니다. 배열을 복사하는 데 사용할 수있는 함수가 있습니까?


7
man memmove그리고man memcpy
Tim Cooper

28
사용하지 마십시오 memcpy, 사용 std::copy. 형식에 의미있는 복사 생성자가 있으면 memcpy잘못된 작업을 수행합니다.
Ed S.

10
실제로 C와 C ++를 동시에 배우려고합니까? 그들은 매우 다른 언어입니다.
Ferruccio 2013

1
저는 C를 조금 배웠고 지금은 최근에 C ++를 배우기 시작했습니다. 온라인 리소스에서 읽은 내용에서 C ++는 C 언어에 대한 많은 추가 기능이있는 언어 일 뿐이라고 생각했습니다.
JL

6
아무도 그것을 언급하지 않았기 때문에 이것을 말하는 것입니다. C ++에서는 거의 모든 경우에 std :: vector를 사용해야합니다. 다른 컨테이너도 유용한 경우가 있지만 대부분의 경우 std :: vector가 가장 좋은 옵션입니다. C ++에서 원시 배열을 사용하지 말고 필요하지 않으면 std :: array를 피하십시오.
Skalli

답변:


79

C ++ 11부터 다음을 사용하여 배열을 직접 복사 할 수 있습니다 std::array.

std::array<int,4> A = {10,20,30,40};
std::array<int,4> B = A; //copy array A into array B

다음은 std :: array 에 대한 문서입니다.


@XAleXOwnZX : 복사 할당을 지원하는 다른 유형과 동일합니다. B = A.
swalog

2
기능은 A의 메모리 주소를 B에 복사하는 것 같습니다. B의 메모리 주소를 변경하지 않고 A의 항목 값을 B에 복사하려고하면. 어떻게 할 수 있습니까?
아론 리

@Aaron_Lee : 방금 테스트했으며 실제로 요소를 별도의 메모리 위치에있는 배열로 복사합니다. 배열 클래스에는 할당 연산자에 대한 자체 오버로드가 분명히 있습니다.
Dave Rove

4
이 두 줄의 코드에 할당 연산자가 없다는 것을 알고 계십니까? 표기법이 할당 연산자처럼 보이지만 호출되는 복사 생성자입니다.
Albino Cordeiro

137

C ++ 솔루션을 요청했기 때문에 ...

#include <algorithm>
#include <iterator>

const int arr_size = 10;
some_type src[arr_size];
// ...
some_type dest[arr_size];
std::copy(std::begin(src), std::end(src), std::begin(dest));

2
erreur : 'begin'은 'std'의 멤버가 아닙니다
David 天宇 Wong

23
@David 天宇 Wong : 이전 컴파일러를 사용하고 있거나 헤더를 포함하지 않았습니다. 그것은에 있어요<iterator>
에드 S.

9
필요한 것을 포함하여 말해야 할 수도 있습니다. 복사가 <algorithm>있습니까?
Jerry Jeremiah

15
std :: begin이 <iterator>에 있다는 것을 설명해야한다면 사람들이 std :: begin에 인터넷 검색을하지 않고 어떤 헤더에 있는지 알아 내야하므로 std :: copy 같은 내용을 복사하지 않을 것입니다. 이유. 댓글로만 답변되는 항목을 아무도 묻지 않으면 더 나은 답변이됩니다. 아마도 내가 당신에게 그것을하라는 메시지 대신에 대답을 편집했을 것입니다.
Jerry Jeremiah

3
begin (src)을 src로, end (src)를 src + arr_size로 변경할 수 있습니다
Calvin

82

다른 사람들이 언급했듯이 C에서는 memcpy. 그러나 이것은 원시 메모리 복사를 수행하므로 데이터 구조에 자체 또는 서로에 대한 포인터가있는 경우 복사본의 포인터는 여전히 원래 개체를 가리 킵니다.

C ++에서 당신은 또한 사용할 수있는 memcpy배열 구성원이, (당신은 또한 C에서 변경 사용할 수도 본질적 유형이다) 그러나 일반적으로, POD하면 memcpy됩니다 되지 허용합니다. 다른 사람들이 언급했듯이 사용할 기능은 std::copy.

그러나 C ++에서는 원시 배열을 거의 사용하지 않아야합니다. 대신 당신도 표준 컨테이너 중 하나를 사용해야합니다 ( std::vector있는 배열 내장, 또한 내가 자바 배열에 가까운 생각에 가장 가까운 - 가까운 일반 C보다 ++ 배열, 참 -하지만, std::deque또는 std::list어떤 경우에는 더 적합 할 수 있음) 또는 std::array내장 배열에 매우 가깝지만 다른 C ++ 유형과 같은 값 의미를 갖는 C ++ 11을 사용하는 경우 . 여기서 언급 한 모든 유형은 할당 또는 복사 구성으로 복사 할 수 있습니다. 또한 반복자 구문을 사용하여 opne에서 다른 것으로 (및 내장 배열에서도) "교차 복사"할 수 있습니다.

이것은 가능성에 대한 개요를 제공합니다 (모든 관련 헤더가 포함되었다고 가정합니다).

int main()
{
  // This works in C and C++
  int a[] = { 1, 2, 3, 4 };
  int b[4];
  memcpy(b, a, 4*sizeof(int)); // int is a POD

  // This is the preferred method to copy raw arrays in C++ and works with all types that can be copied:
  std::copy(a, a+4, b);

  // In C++11, you can also use this:
  std::copy(std::begin(a), std::end(a), std::begin(b));

  // use of vectors
  std::vector<int> va(a, a+4); // copies the content of a into the vector
  std::vector<int> vb = va;    // vb is a copy of va

  // this initialization is only valid in C++11:
  std::vector<int> vc { 5, 6, 7, 8 }; // note: no equal sign!

  // assign vc to vb (valid in all standardized versions of C++)
  vb = vc;

  //alternative assignment, works also if both container types are different
  vb.assign(vc.begin(), vc.end());

  std::vector<int> vd; // an *empty* vector

  // you also can use std::copy with vectors
  // Since vd is empty, we need a `back_inserter`, to create new elements:
  std::copy(va.begin(), va.end(), std::back_inserter(vd));

  // copy from array a to vector vd:
  // now vd already contains four elements, so this new copy doesn't need to
  // create elements, we just overwrite the existing ones.
  std::copy(a, a+4, vd.begin());

  // C++11 only: Define a `std::array`:
  std::array<int, 4> sa = { 9, 10, 11, 12 };

  // create a copy:
  std::array<int, 4> sb = sa;

  // assign the array:
  sb = sa;
}

1
memcpy 예제는 잘못되었습니다. 소스와 대상이 전환됩니다.
AT-학생

1
사실,이 memcpy예제 의 유일한 실수는 아닙니다 . 크기도 잘못되었습니다. 이제 고쳤습니다. 감사합니다.
celtschk

왜 std의 이름 공간을 사용하는 대신 항상 std를 작성하고 있습니까?
Black

memcpy (b, a, sizeof a); 할 수 없습니까? 너무?
rodi

Java 배열은 크기가 고정되어 있기 때문에 std:array보다 비슷 std::vector합니다.
Bart van Heukelom

17

당신은을 사용할 수 있습니다 memcpy(),

void * memcpy ( void * destination, const void * source, size_t num );

memcpy()num가리키는 위치에서가 가리키는 source메모리 블록 으로 바이트 값을 직접 복사합니다 destination.

는 IF destinationsource중복, 당신은 사용할 수 있습니다 memmove().

void * memmove ( void * destination, const void * source, size_t num );

memmove()num가리키는 위치에서가 가리키는 source메모리 블록 으로 바이트 값을 복사합니다 destination. 복사는 마치 중간 버퍼가 사용 된 것처럼 이루어 지므로 대상과 소스가 겹칠 수 있습니다.


3
여기에서 -1을해야합니다. OP는 구체적으로 C ++ 솔루션을 요구하고 있으며이 답변 memcpy은 잘못된 상황 , 즉 바이트 복사가 불충분 한 상황에 대해 아무것도 말하지 않습니다.
Ed S.

2
@EdS. 눈치 채지 못한 경우 OP는 이제 C 또는 C ++ 솔루션을 요청 합니다.
자폐증 Autistic

4
내가 대답했을 때 OP는 C / C ++ 솔루션을 요구하고 있었지만 개인적으로는 "C / C ++"가 두 언어 모두에 대한 모욕이라고 생각합니다. :)
Deepu 2013-04-22

공평하게, 나는 그것이 변화하고 있다는 것을 깨닫지 못했습니다. 어쩌면 그것은 더 일찍 말했고 나는 그것을 놓쳤을 것입니다. -1 제거됨.
Ed S.

2
@EdS 나는 2 분이라고 생각했지만이 답변이 게시 된 시점에 관계없이 질문은 C와 C ++ 모두에 대해 언급되었습니다. 내가 틀렸고 어떤 시점에서 질문이 C ++로만 언급 되더라도 반대 투표는 보증되지 않았습니다.
Jim Balter 2013

16

memcpyC, std::copyC ++에서 사용합니다 .


작은 배열의 경우 함수 호출 오버 헤드가 발생하지 않는다고 가정 memcpy합니다 (컴파일러 내장이어야 함)?
wcochran

@Mehrdad 나는 달리 말하지 않았다; 그냥 댓글을 달아주세요. 그리고 나도 반대표를 던지지 않았습니다.
MD XF

12

나는 Ed S.의 대답을 좋아하지만 이것은 고정 크기 배열에서만 작동하며 배열이 포인터로 정의 된 경우에는 작동하지 않습니다.

따라서 배열이 포인터로 정의되는 C ++ 솔루션 :

#include<algorithm>
...
const int bufferSize = 10;
char* origArray, newArray;
std::copy(origArray, origArray + bufferSize, newArray);

참고 : buffersize1 로 공제 할 필요가 없습니다 .

  1. 처음부터 마지막까지 [first, last) 범위의 모든 요소를 ​​복사합니다.-1

참조 : https://en.cppreference.com/w/cpp/algorithm/copy


10

C에서는 memcpy. C ++에서는 헤더 std::copy에서 사용 합니다 <algorithm>.


3

C ++ 11 Copy()에서는 표준 컨테이너에서 작동 하는 것을 사용할 수 있습니다.

template <typename Container1, typename Container2>
auto Copy(Container1& c1, Container2& c2)
    -> decltype(c2.begin())
{
    auto it1 = std::begin(c1);
    auto it2 = std::begin(c2);

    while (it1 != std::end(c1)) {
        *it2++ = *it1++;
    }
    return it2;
}

std::end성능상의 이유로 루프 에서 제거 하는 것이 더 나은 아이디어입니다 (c1은 루프 중에 반복기를 변경하거나 무효화하지 않으므로 끝을 다시 계산할 필요가 없습니다).
celtschk

3

여기서는 C 및 C ++ 언어에 대해 배열을 처리하는 두 가지 방법을 제공합니다. memcpycopy 둘 다 C ++에서 사용할 수 있지만 copy 는 C에서 사용할 수 없습니다. C에서 배열을 복사하려는 경우 memcpy 를 사용해야합니다 .

#include <stdio.h>
#include <iostream>
#include <algorithm> // for using copy (library function)
#include <string.h> // for using memcpy (library function)


int main(){

    int arr[] = {1, 1, 2, 2, 3, 3};
    int brr[100];

    int len = sizeof(arr)/sizeof(*arr); // finding size of arr (array)

    std:: copy(arr, arr+len, brr); // which will work on C++ only (you have to use #include <algorithm>
    memcpy(brr, arr, len*(sizeof(int))); // which will work on both C and C++

    for(int i=0; i<len; i++){ // Printing brr (array).
        std:: cout << brr[i] << " ";
    }

    return 0;
}

4
using namespace std;나쁜 습관 입니다. 절대 사용하지 마십시오. cplusplus.com 대신 cppreference.com을 사용하십시오. 여기에는 훨씬 더 나은 최신 표준 문서가 포함되어 있습니다. stdio.h++ C에 해당하는은 cstdio을 사용하는 대신,. 또한 코드는 상당히 비 관상적인 C ++입니다. C와 C ++에 대한 별도의 솔루션을 선보였다면 훨씬 더 명확 할 것 같습니다.
tambre

3

코드에 표준 라이브러리를 포함하기 만하면됩니다.

#include<algorithm>

배열 크기는 다음과 같이 표시됩니다. n

이전 어레이

int oldArray[n]={10,20,30,40,50};

이전 배열 값을 복사해야하는 새 배열 선언

int newArray[n];

이것을 사용하십시오

copy_n(oldArray,n,newArray);

1

첫째, C ++로 전환하기 때문에 기존 array 대신 vector 를 사용하는 것이 좋습니다 . 게다가 배열이나 벡터를 복사하는 것이 최선의 선택입니다.std::copy

복사 기능 사용 방법은이 페이지를 참조하십시오. http://en.cppreference.com/w/cpp/algorithm/copy

예:

std::vector<int> source_vector;
source_vector.push_back(1);
source_vector.push_back(2);
source_vector.push_back(3);
std::vector<int> dest_vector(source_vector.size());
std::copy(source_vector.begin(), source_vector.end(), dest_vector.begin());
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.