반응형

[리눅스 커널] 우분투 커널 소스 다운로드 하기

 

Ubuntu에는 커널 소스가 포함되어 있지 않습니다. /usr/src에는 커널의 헤더 파일만 있는 것을 볼 수 있습니다. 

이번에는 Ubuntu의 커널 소스를 다운로드 받아보겠습니다. 

 

커널 버전 확인 하기

아래 명령어를 이용해 커널의 버전을 확인할 수 있습니다. 

아래는 5.15.0-69 버전인 것을 볼수 있습니다.

#uname -r

 

참고로 OS 버전은 아래 명령어를 이용합니다. 

#cat /etc/os-release

 

버전에 맞는 커널 다운로드

커널에 대한 모든 버전의 소스는 아래에서 다운로드할 수 있습니다.

https://kernel.org/

 

The Linux Kernel Archives

 

kernel.org

 

apt 데이터베이스를 업데이트한 후 다음 명령을 실행하여 apt-get을 사용하여 linux-source를 설치할 수 있습니다

apt-get -y install linux-source

다운로드가 되면 아래 폴더 하나랑 압축파일 하나가 다운로드된 것을 볼 수 있습니다. 

linux-source-5.4.0

linux-source-5.4.0.tar.bz2

 

그리고 그 압축파일을 해제하면 커널 소스를 볼 수 있습니다. 

파일이 커서 그런지 압축해제하는데, 시간이 좀 걸립니다. 

#tar xvf linux-source-5.4.0.tar.bz2

 

linux-source-5.4.0 폴더에 들어가보면 커널 소스가 있는 것을 확인할 수 있습니다.

반응형
반응형

[C++11] shared_ptr 정리 및 간단한 사용 예제

 

shared_ptr은  C++11부터 사용 가능한 smart pointer입니다.

 

std::shared_ptr 란

포인터를 통해 객체의 공유 소유권을 유지하는 스마트 포인터입니다. 힙 메모리에 객체를 위한 메모리와 참조 카운터를 위한 메모리가 할당됩니다. 여러 shared_ptr 객체가 동일한 객체를 소유할 수 있습니다. 다음 중 하나가 발생하면 개체가 소멸되고 메모리 할당이 해제됩니다.
- 객체를 소유하고 있는 마지막 남은 shared_ptr이 파괴됩니다.
- 객체를 소유하고 있는 마지막 남은 shared_ptr에는 operator= 또는 reset()을 통해 다른 포인터가 할당됩니다.
- 객체는 생성 중에 shared_ptr에 제공되는 delete-expression 또는 사용자 지정 삭제자를 사용하여 소멸됩니다.

 

std::shared_ptr 사용법

1. object를 가르키는 shared_ptr 생성자 호출할 수 있습니다. => std::shared_ptr<T> ptr(T *);

2.  새로운 shard_ptr 객체를 생성하기 위해 std::make_shard를 사용할 수 있습니다.
=> std::shared_ptr<T> ptr = std::make_shared<T>(); 

3. 동일한 포인터를 공유할 수 있습니다. 공유하는 변수가 늘어날수록 참조 카운터가 증가하며, use_count() 함수를 사용하여 참조 카운터를 확인할 수 있습니다. reset() 함수는 nullptr처럼 포인터를 해제하고 참조 카운터를 감소시킵니다.

=> std::shared_ptr<T> ptr1 = std::make_shared<T>(); 

=> std::shared_ptr<T> ptr2 = ptr2;

 

#include <iostream>
#include <memory>

class Student
{
public:
    Student() { std::cout << __FUNCTION__ << std::endl; }
    ~Student() { std::cout << __FUNCTION__ << std::endl; }

    std::shared_ptr<Student> getPtr()
    {
        return std::shared_ptr<Student>(this);
    }
};

int main()
{
    Student* p = new Student;

    // 1. p object를 가르키는 shared_ptr 생성자 호출합니다.
    std::shared_ptr<Student> ptr1(p); 
    std::cout << "ptr1.use_count(): " << ptr1.use_count() << std::endl;

    // 2. 새로운 shard_ptr 객체를 생성하기 위해 std::make_shard를 사용합니다.
    //  std::make_shard는 객체와 참조 카운터를 위한 메모리를 할당합니다.
    std::shared_ptr<Student> ptr2 = std::make_shared<Student>(); 
    std::cout << "ptr2.use_count(): " << ptr2.use_count() << std::endl;

    // 3. 동일한 포인터를 공유합니다. (ptr3과 ptr4)

    std::shared_ptr<int> ptr3(new int(5));
    std::cout << "ptr3.use_count(): " << ptr3.use_count() << std::endl;
    std::cout << "ptr3 value : " << *ptr3 << std::endl;

    std::shared_ptr<int> ptr4 = ptr3;
    std::cout << "ptr4.use_count(): " << ptr4.use_count() << std::endl;
    std::cout << "ptr4 value : " << *ptr4 << std::endl;

    std::cout << "ptr4 reset! " <<  std::endl;
    ptr4.reset();
    std::cout << "ptr3.use_count(): " << ptr3.use_count() << std::endl;

    return 0;
}

std::shared_ptr를 사용할 때 주의할 점

개체의 소유권은 다른 shared_ptr에 값을 할당하거나 복사 구성을 통해서만 다른 shared_ptr과 공유할 수 있습니다. 다른 shared_ptr이 소유한 원시 기본 포인터를 사용하여 새 shared_ptr을 구성하면 정의되지 않은 동작이 발생합니다.

 

아래 예제는 ptr2에 ptr1에서 객체의 주소를 return 받아 할당하도록 하였는데, 실행파일이 죽게됩니다.

#include <iostream>
#include <memory>

class Student
{
public:
    Student() { std::cout << __FUNCTION__ << std::endl; }
    ~Student() { std::cout << __FUNCTION__ << std::endl; }

    std::shared_ptr<Student> getPtr()
    {
        return std::shared_ptr<Student>(this);
    }
};

int main()
{
    Student* p = new Student;

    //p object를 가르키는 shared_ptr 생성자 호출합니다.
    std::shared_ptr<Student> ptr1(p); 
    std::cout << "ptr1.use_count(): " << ptr1.use_count() << std::endl;

    // ptr2에 ptr1에서 객체의 주소를 return 받아 할당하도록 해봅니다.
    std::shared_ptr<Student> ptr2 = ptr1->getPtr(); // 
    std::cout << "ptr2.use_count(): " << ptr2.use_count() << std::endl;

    return 0;
}

Student라는 클래스를 하나 동적선언하였고, 이 객체를 두 개의 shared_ptr ptr1, ptr2에 할당하였습니다.  ptr2를 생성하는 시점에 ptr1에 의해서 이미 Student 객체의 파괴자는 호출되어 객체가 소멸됩니다. 객체가 없는 상태에서 ptr2에서 다시 파괴자를 호출하는 구조이기 때문에 실행파일이 죽게됩니다. 

#include <iostream>
#include <memory>

class Student
{
public:
    Student() { std::cout << __FUNCTION__ << std::endl; }
    ~Student() { std::cout << __FUNCTION__ << std::endl; }

    std::shared_ptr<Student> getPtr()
    {
        return std::shared_ptr<Student>(this);
    }
};

int main()
{
    Student* p = new Student;

    //p object를 가르키는 shared_ptr 생성자 호출합니다.
    std::shared_ptr<Student> ptr1(p); 
    std::cout << "ptr1.use_count(): " << ptr1.use_count() << std::endl;

    //p object를 가르키는 shared_ptr 생성자 호출합니다.
    std::shared_ptr<Student> ptr2(p); 
    std::cout << "ptr2.use_count(): " << ptr2.use_count() << std::endl;

    return 0;
}

참조

https://en.cppreference.com/w/cpp/memory/shared_ptr

 

std::shared_ptr - cppreference.com

template< class T > class shared_ptr; (since C++11) std::shared_ptr is a smart pointer that retains shared ownership of an object through a pointer. Several shared_ptr objects may own the same object. The object is destroyed and its memory deallocated when

en.cppreference.com

https://en.cppreference.com/w/cpp/memory/unique_ptr

 

std::unique_ptr - cppreference.com

(1) (since C++11) template <     class T,     class Deleter > class unique_ptr ; (2) (since C++11) std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of sco

en.cppreference.com

 

반응형
반응형

[리눅스 명령어] ar 명령어 - 정적 라이브러리 만들기

 

ar 명령어란

정적 라이브러리는 컴파일된 오브젝트 파일들이 하나의 아카이브로 묶여있는 형태로 되어 있습니다. 이 오브젝트 파일들을 묶어주는 명령어가 ar 명령어입니다. 

 

정적 라이브러리 생성 명령어

ar rscv [라이브러리 이름] [오프젝트 파일들] 

r : 새로운 오브젝트 파일이면 추가하고, 기존 파일이면 치환합니다.

s : 인덱스를 생성해줍니다.

c : 라이브러리 파일을 생성합니다. 

v : 자세한 내용을 출력해줍니다.

 

정적 라이브러리 파일에서 오브젝트 제거

ar ds [라이브러리 이름] [오프젝트 파일들] 

d : 오브젝트 파일을 삭제합니다. 

 

정적 라이브러리 파일 리스트 출력

ar tv [라이브러리 이름] 

t :정적 라이브러리에 있는 오브젝트 파일 리스트를 출력합니다. 

 

정적 라이브러리 파일에서 오브젝트 파일 추출

ar xv [라이브러리 이름] 

x : 아카이브에서 오브젝트 파일을 추출합니다.

 

 

사용 예제

 

반응형
반응형

[googletest] ASSERT_EQ와 같은 ASSERT_xx 단헌 함수 간단 사용 예제

 

ASSERT_XX 사용법

기대하는 값과 실제 값을 비교하기 위한 테스트 함수입니다. 

ASSERT_XX (기대값, 실제값) 형식으로 사용합니다. 

EQ(==), NE(!=), LT(<), GT(>), LE(<=), GE(>=), STREQ(문자열 비교), STRCASEEQ(문자열 대소문자 무시 비교), DOUBLE_EQ(부동소수점 비교)를 사용합니다.

 

사용 예제

#include <gtest/gtest.h>
#include <string>

TEST(SampleTest, Test1){
	int value = 4;
	ASSERT_EQ(4, value);
}

TEST(SampleTest, Test2){
	int value = 4;
	ASSERT_NE(5, value);
}

TEST(SampleTest, Test3){
	int value = 4;
	ASSERT_LT(3, value);
}

TEST(SampleTest, Test4){
	int value = 4;
	ASSERT_GT(3, value);
}

TEST(SampleTest, Test5){
	int value = 4;
	ASSERT_LE(4, value);
}

TEST(SampleTest, Test6){
	int value = 4;
	ASSERT_GE(4, value);
}

TEST(SampleTest, Test7){
	std::string s1 = "hello";
	std::string s2 = "hello";
	ASSERT_EQ(s1, s2);
}

TEST(SampleTest, Test8){
	const char* s3 = "hello";
	const char* s4 = "hell2";
	ASSERT_STREQ(s3,s4);
}

테스트 결과는 아래와 같이 출력됩니다.

 

 

반응형

+ Recent posts