정적인 메모리 할당에 관해서..

song의 이미지

다음과 같은 구문이 있습니다. 제 나름대로 생각하는 부분이 맞는지 설명좀 부탁드릴게요.

char buffer[512];

snprintf(buffer,512,"select * from table where type=0 limit 1");
printf("%s\n",buffer);

snprintf(buffer,512,"select * from table limit 1");
printf("%s\n",buffer);

두번째의 buffer뒤에는 어떤 쓰레기 값이 없이 "select * from table limit 1" 의 데이터가 그대로 들어가지던대
snprintf함수가 값을 할당하기전에 변수를 초기화 해주기때문인가요?

두번째로 드리는 질문은
함수가 끝나고나서 이 buffer 의 메모리를 해제 해주어야 하지 않나요?
함수가 끝나면 자동으로 알아서 해제를 해주는건지 아니면 다른 해제 방법이 있나요?

jemiro의 이미지

답변만 드리자면,
1. 메모리를 초기화 하지는 않습니다.
"select * from table where type=0 limit 1" 라는 문자열의 젤끝에,
'\0'이 들어 가 있어서, snprintf 두buffer에 NULL까지 넣어줍니다.
그래서 printf는 뒤에 가비지 데이터는 출력하지 않고....
\0까지만 깨끗하게 출력해주는것입니다.

2. 함수와 함께 메모리가 해제 됩니다.
malloc 계열의 함수로 메모리를 동적할당 해주었을때만
꼭 free를해주어야 합니다.

3. malloc, free 사용법은 알고 계시겠지만, 간단한 예제..

char *buffer;
buffer = (char *) malloc(512);
if (!buffer)
    exit(1);
memset(buffer, 0, 512);
snprintf(buffer, sizeof buffer - 1,
             "select * from table where type=0 limit 1");
printf("%s\n",buffer);

if (buffer)
    free(buffer);

return 0;

song wrote:
다음과 같은 구문이 있습니다. 제 나름대로 생각하는 부분이 맞는지 설명좀 부탁드릴게요.

char buffer[512];

snprintf(buffer,512,"select * from table where type=0 limit 1");
printf("%s\n",buffer);

snprintf(buffer,512,"select * from table limit 1");
printf("%s\n",buffer);

두번째의 buffer뒤에는 어떤 쓰레기 값이 없이 "select * from table limit 1" 의 데이터가 그대로 들어가지던대
snprintf함수가 값을 할당하기전에 변수를 초기화 해주기때문인가요?

두번째로 드리는 질문은
함수가 끝나고나서 이 buffer 의 메모리를 해제 해주어야 하지 않나요?
함수가 끝나면 자동으로 알아서 해제를 해주는건지 아니면 다른 해제 방법이 있나요?

B00m의 이미지

snprintf 함수가 버퍼를 초기화 해주는 것은 아니구 포멧 스트링은 끝에 null 문자까지 다 버퍼에 써 주므로 쓰레기 값이 없이 나와야 정상입니다..

단, 예외는 snprintf 는 포멧 스트링이 주어진 버퍼의 크기를 넘게 되면 null 이 포함되지 않으므로 쓰레기값이 나올 수 있습니다..

따라서 정석적으로 한다면 그부분에 대한 처리도 해주셔야 맞습니다.

그리고 함수내에 배열로 잡은 변수는 스택에 잡히게 되므로 함수가 끝나면 자동으로 무효화 되게 되어있습니다..

따라서 따로 메모리 해지해 주면 안됩니다.

moonzoo의 이미지

char buffer[512]; 

1번
snprintf(buffer,512,"select * from table where type=0 limit 1"); 
printf("%s\n",buffer); 

2번
snprintf(buffer,512,"select * from table limit 1"); 
printf("%s\n",buffer); 

buffer 의 내용.
1번 실행후
select * from table where type=0 limit 1$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

2번 실행후
select * from table limit 1$pe=0$limit 1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

편의상 $ = NULL , xxx... = 쓰레기 문자들..(임의로..정한것임)

보시는 바와 같이 snprintf는 buffer에 문자열 쓰는 것이므로.

마지막에 널 문자를 씁니다.(문자열 끝에는 항상 NULL이 존재)

printf의 %s 옵션은 첫 주소부터 NULL문자를 만날때 까지 출력하는 것이므로

NULL문자 뒤에 쓰레기 문자가 있건 예전의 data들이 지워지지 않고 존재하건

상관없이 NULL문자까지만 찍게 됩니다.

1번 실행후 2번 실행시 초기화 한 후에 하는 것이 아니며

그대로 위에다가 덮어 쓰고 , 널 문자로 경계를 표시하는 것입니다.

또한 함수내에서 선언한 변수들은 함수 끝날때 알아서 관리되므로

따로 해제하는 등의 관리해 주실 필요가 전혀 없습니다.

charsyam의 이미지

char buffer[512]; 이렇게 함수 안에서 선언할 경우에 지역 변수는

스택에 공간이 생깁니다. 그렇기 때문에, 함수가 종료되면, 스택 공간이

복구되고, 이 때, 자동으로 사라지게 됩니다. 그럼 고운 하루.

=========================
CharSyam ^^ --- 고운 하루
=========================

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.