C에서 문자열 리터럴의 수명? 범위?

FIFO의 이미지

제목이 애매한데 오늘 코딩하다 겪은 일입니다.
(빌어먹을 vi 습관 때문에 ESC 누르다 4번 날렸습니다.
지금은 아예 메모장에서 써서 옮깁니다. 이거 좀 막을 수 없을런지)

FILE *AAA_File;	// 이건 전역변수로 했음
AAA_File = fopen("AAA_XXXX.txt", "r");

이렇게 했는데... XXXX에 해당하는 부분 문자열만 좀 바꿨더니 계속 에러 나는 겁니다...
errno값을 보니 ENO... 뭐라나 여하튼 파라미터가 empty하다는 겁니다.
허걱? 그래서 아래처럼 바꿨더니... 잘 됩니다...

FILE *AAA_File;	// 이건 전역변수로 했음
char AAA_Path[] = "AAA_XXXX.txt";	// 이건 fopen 부른 함수의 지역변수로 했음
AAA_File = fopen(AAA_Path, "r");

여하튼 되긴 됐지만... 처음에 짠 것처럼 그냥 문자열 리터럴은 아무데서나 써도 수명(?)이 전역변수와 동일한걸로 알고 있었는데... 아닌가요?
제가 알기론 C 표준에서 그렇게 되어 있는걸로 알고 있었는데...
C 표준에 의거한 문자열 리터럴의 수명은 어떻게 되는지 궁금합니다.

ymir의 이미지

ENOENT 는 fopen 의 첫번째 parameter 에 지정된 대상 파일이 존재하지 않는다는 뜻입니다.
read 의 경우에는 대상 파일이 있어야 합니다.
errno 를 이용하여 적절히 메시지를 뿌려주고 처리하면 되겠네요.

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

FIFO의 이미지

상황을 자세히 쓰자면...

애당초 파일을 잘 열던 프로그램이었습니다.
파일명은 AAA.txt였고 fopen("AAA.txt", "r");로 잘 열렸습니다.
그런데 이름을 AAA_XXXX.txt로 바꾸고 fopen("AAA_XXXX.txt", "r");로 바꾸니 안 열려서
다시 AAA.txt로 돌려놔도 안되더군요.

권한은 애당초부터 rwxrwxrwx였고, vi로도 잘 열어서 내용 확인 했고, fuser로 잡고 있는 프로세스가 없음도 확인했습니다.
그런데 저 프로그램으로만 갑자기 안 열리더군요.

그래서 아래쪽 코드와 같이 바꾸니 그때부터 잘 열린다는 겁니다.
그러니까 txt 파일쪽의 문제가 아니라는 말씀이죠.

바꾼 것은 문자열 리터럴을 직접 쓰느냐 배열 변수를 이용해서 쓰느냐의 차이뿐이었습니다.
그래서 문자열 리터럴 관련된 C 표준을 문의드린 것입니다.

ymir의 이미지

알고 계신대로 string literal 은 ro data segment 에 얌전히 있을거고..
프로그램이 실행되는 동안에는, address 만 알고 있으면 언제든지 접근 가능합니다.

실행방식까지 완전히 같은 조건에서, 변수 전달방식만 다른데, 결과도 다른 케이스는 처음보는데..;;
어쨌든 파일명을 어떻게 전달하던지, 결과는 동일할겁니다.

아무래도 문제가 발생했을 때의, errno 를 정확하게 체크해 보심이 좋을 듯 합니다.

어떤 방식으로 실행시켰는지 알 수 없어서.. 일반론으로 좀 더 첨언하자면..
fopen 으로 주어진 파일명에 경로가 없으니..
해당 프로그램은 무조건 CWD 에서 파일을 찾게됩니다.
명시적으로 chdir() 과 같은 함수를 써서, 파일이 위치한 경로로 변경하지 않는 한..
실행시킨 위치에서 파일을 찾게 됩니다.

혹시 strace 가 설치되어 있다면, 다음과 같은 옵션으로 실행 당시의 환경 변수 및 몇몇 시스템 콜 호출 내역을 알 수 있습니다.

strace -f -v -e execve,open,chdir

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

FIFO의 이미지

strace라는게 있었군요... 좋은 내용 알려주셔서 감사합니다. 나중에 꼭 확인해봐야겠네요.
음... 그리고 저 문제 생겼을때 경로명을 절대경로로도 바꿔서 해봤었습니다. 역시 마찬가지 에러 그대로 나오더군요...
하여간 생전 처음 겪었던 일이라... 황당할 뿐입니다...

lovian의 이미지

해당 문자열은 바이너리를 검색해보셔도 아시겠지만,
아주 박혀있는 값입니다.

해당 문자열은 프로그램 로딩시부터 언로딩 시점까지 유효하겠죠 :)

문제점은 윗분께서 답해주셨으니.
-----------------
한글을 사랑합니다.

-----------------
한글을 사랑합니다.

댓글 달기

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 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • 사용할 수 있는 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>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • You can use Textile markup to format text.
  • 사용할 수 있는 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>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 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>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.