1. 문제 개요C와 C++에서 문자열 리터럴은 코드에서 자주 사용되지만, 이를 수정하려고 하면 예기치 않은 오류가 발생할 수 있습니다. 문자열 리터럴이 저장되는 위치와 수정 불가능한 이유를 이해하면 프로그램 안정성을 높이고 디버깅 과정을 단축할 수 있습니다. 간단한게 문자열 리터럴이 어디에 저장되는지 알아보고, 메모리에 대해서 자세히 깊이있게 궁금하다면 글을 끝까지 읽어보세요!2. 문자열 리터럴의 저장 위치2.1 문자열 리터럴의 저장 원리문자열 리터럴은 일반적으로 읽기 전용 데이터(Read-Only Data) 섹션에 저장됩니다. 이 영역은 실행 파일의 .rodata 섹션에 위치하며, 운영 체제에 의해 읽기 전용으로 설정됩니다.예제:char *s = "hello";"hello" 문자열은 .rodata 섹션..
전체 글
C 언어에서 동적 메모리를 할당할 때 사용하는 malloc() 함수는 결과값으로 void * 타입의 포인터를 반환합니다. 하지만 이를 특정 타입으로 캐스팅(형변환, cast)해야 하는지 여부는 오랜 시간 논의되어 온 주제입니다. 결론적으로, C에서는 malloc() 결과를 형변환(타입캐스팅)하지 않는 것이 권장됩니다. 그 이유를 아래에서 설명합니다.1. 형변환(타입캐스팅)이 불필요한 이유1.1. 자동 형 변환 지원C 언어에서는 void * 타입의 포인터를 다른 포인터 타입으로 자동 변환합니다.따라서 명시적으로 형변환하지 않아도 컴파일러가 올바른 형 변환을 수행합니다.int *arr = malloc(sizeof(int) * 10); // 캐스팅 불필요1.2. 코드 간결성형변환은 코드의 가독성을 떨어뜨립니다..
1. 문제 개요C 언어에서 문자열을 선언할 때 두 가지 주요 방식이 있습니다:char s[] = "hello";char *s = "hello";이 두 방식은 비슷해 보이지만, 메모리 배치와 수정 가능성에서 중요한 차이를 보입니다. 이를 명확히 이해하면 메모리 관련 오류를 방지하고 더 안전한 코드를 작성할 수 있습니다.2. char s[]와 char *s의 차이점2.1 char s[]의 동작 원리문자열 복사: "hello" 문자열은 읽기 전용 메모리에 저장되고, 배열 s는 해당 문자열을 복사하여 스택 메모리에 저장합니다.수정 가능: 배열 s는 복사된 데이터이므로 수정 가능합니다.char s[] = "hello";s[0] = 'H'; // 정상적으로 작동메모리 배치:읽기 전용 메모리에 "hello"가 저장..
1. 문제 개요C와 C++에서 전역 변수는 전역에서 접근 가능하며 편리하지만, 프로그램 유지보수성과 테스트에 악영향을 줄 수 있다는 이유로 종종 "피해야 할 것"으로 간주됩니다. 하지만, 전역 변수를 무조건 나쁜 것으로 간주하기 전에, 이들의 장점과 단점을 이해하고 적절히 사용하는 것이 중요합니다.2. 전역 변수의 장점2.1 간결한 코드전역 변수를 사용하면 여러 함수에서 공유해야 하는 데이터를 매번 인자로 전달할 필요가 없습니다.코드가 간결해지고 함수 호출이 단순해집니다.예제:int globalCounter = 0;void increment() { globalCounter++;}void display() { printf("Counter: %d\n", globalCounter);}2.2 메모리와..
1. 개요Java에서 equals와 hashCode 메서드를 올바르게 재정의하는 것은 중요합니다. 특히, HashMap, HashSet 등 해싱 기반 컬렉션에서 객체를 효율적으로 저장하고 검색하려면 필수적입니다. 이 문서에서는 왜 이 두 메서드를 재정의해야 하는지, 재정의하지 않으면 발생할 수 있는 문제와 함께 구체적인 예제와 함께 설명합니다.2. equals와 hashCode의 역할2.1 equals 메서드객체 비교: 두 객체가 논리적으로 같은지 판단합니다.기본 구현: Object 클래스의 기본 equals는 참조 주소를 비교하므로, 동일 객체가 아니면 항상 false를 반환합니다.2.2 hashCode 메서드해싱 알고리즘: 객체의 해시 코드를 반환합니다. 이 해시 코드는 객체를 HashMap, Has..
프로그래밍에서 함수(Function)는 자주 반복되는 코드를 재사용 가능하게 만들어주는 도구입니다. C언어에서 함수는 프로그램을 구조화하고 가독성을 높이는 중요한 역할을 합니다. 이 글에서는 C언어의 함수에 대해 기본 개념부터 활용법까지 상세히 설명하겠습니다.1. 함수란 무엇인가?함수는 특정 작업을 수행하는 코드 블록입니다. 함수는 프로그램을 작은 작업 단위로 나눔으로써 코드 재사용성을 높이고 유지보수를 쉽게 만듭니다.함수의 주요 특징입력(Input): 매개변수를 통해 데이터를 받음.처리(Process): 함수 내부에서 작업 수행.출력(Output): 반환 값을 통해 결과를 돌려줌.2. 함수의 선언과 정의C언어에서 함수를 사용하려면 선언(Declaration)과 정의(Definition)가 필요합니다.함..
1. 문제 개요C 언어에서 배열을 사용할 때, 경계 밖(out-of-bounds)으로 데이터를 읽거나 쓰는 실수는 프로그램에 치명적인 오류를 유발할 수 있습니다. 이 글에서는 배열 경계 밖 접근의 위험성을 살펴보고, 프로그램과 시스템을 안전하게 보호하는 방법을 제시합니다.2. 배열 경계 밖 접근의 위험성2.1 ISO C 표준의 "정의되지 않은 동작"ISO C 표준에서는 배열 경계 밖 접근을 "정의되지 않은 동작(undefined behavior)"으로 간주합니다. 이는 컴파일러나 실행 환경에 따라 다음과 같은 예측할 수 없는 결과를 초래할 수 있습니다:프로그램이 계속 실행되지만 잘못된 값을 반환.세그멘테이션 오류(segmentation fault)로 프로그램이 비정상 종료.메모리 오염으로 다른 코드에 영..
1. 문제 개요C와 C++에서는 const 키워드와 포인터를 조합하여 다양한 읽기 및 쓰기 제한을 설정할 수 있습니다. const int*, int* const, 그리고 int const* const는 자주 혼동되지만, 실제로는 엄격한 규칙에 따라 동작합니다. 본 글에서는 이를 명확히 이해하고 올바르게 사용하는 방법을 알아봅니다.2. const와 포인터의 기본 규칙포인터 선언에서 const 키워드는 읽기 제한을 설정합니다. 다음은 선언을 읽는 기본 규칙입니다:가장 가까운 const가 무엇을 제한하는지 확인합니다.선언을 오른쪽에서 왼쪽으로 읽는 방식이 이해에 유용합니다.기본 형태와 의미선언의미int* ptrptr는 정수를 가리키는 포인터입니다.const int* ptrptr는 상수 정수를 가리키는 포인터입..
1. 문제 개요C 언어에서 초기화되지 않은 포인터를 사용하면 프로그램이 예기치 않게 크래시되거나 세그멘테이션 오류(segmentation fault)가 발생할 수 있습니다. 이 글에서는 이러한 문제가 발생하는 이유와 이를 방지하기 위한 방법을 살펴보겠습니다.2. 초기화되지 않은 포인터란?포인터는 다른 변수의 주소를 저장하는 변수입니다. 하지만 초기화되지 않은 포인터는 유효하지 않은 메모리 주소를 가리킵니다. 예를 들어:int *ptr;*ptr = 10; // 오류 발생!여기서 ptr은 초기화되지 않았으므로 가리키는 메모리가 불확실합니다. 이 상태에서 메모리를 참조하면 세그멘테이션 오류가 발생합니다.3. 초기화되지 않은 포인터로 인한 일반적인 오류3.1 데이터 쓰기 오류int *ptr;*ptr = 42;..