C 동적할당(malloc, free) 질문 드립니다.

kaki2981의 이미지

struct info
{
	char s[256];
	int len;
	int words;
};
int main(void)
{
	struct info* inputs = (struct info*) malloc(sizeof(struct info)*n);
	for (int i = 0; i < n + 1; i++)
	{
		char str[256];
		gets(str);
 
		for (int j = 0; j < strlen(str); j++)
			inputs[i].s[j] = str[j];
 
		inputs[i].len = strlen(str);
		inputs[i].words = CountWords(str); // CountWords는 return int
	}
	free(inputs);
	return 0;
}

main 함수에서 질문과 관련있다고 생각하는 부분만 올렸습니다.
제가 이해하는 malloc의 용법은 다음과 같습니다.

sizeof(info)*n 만큼의 크기를 임시로 할당받습니다. 이 힙 영역에 해당하는 주소값을 inputs가 가지고 있습니다.
inputs를 통해서 malloc으로 할당받은 공간에서 작업한 후, free(inputs)으로 그 공간을 해제합니다.

위 코드대로 실행하면 free(inputs)에서 inputs이 공간을 제대로 참조하고 있지 못한 것과 같은 오류가 발생합니다.
inputs를 통해 할당된 공간으로 접근했다고 생각했는데 어디서 잘못됐는지 잘 모르겠습니다.

익명 사용자의 이미지

보통 이렇게 하지 않나요?

struct info
{
        char s[256];
        int len;
        int words;
};
 
int main(void)
{
        int n=10;
        struct info* inputs[n];
 
        for (int i = 0; i < n + 1; i++)
        {
                inputs[i] = (struct info*) malloc(sizeof(struct info));
        }
 
        for (int i = 0; i < n + 1; i++)
        {
		char str[256];
		gets(str);
 
		for (int j = 0; j < strlen(str); j++)
			inputs[i]->s[j] = str[j];
 
		inputs[i]->len = strlen(str);
		inputs[i]->words = CountWords(str); // CountWords는 return int
        }
        for (int i = 0; i < n + 1; i++)
        {
                if(inputs[i]!=NULL)
                        free(inputs[i]);
        }
        return 0;
}
kaki2981의 이미지

올려주신대로 해볼게요! 감사합니다.

raymundo의 이미지

할당된 공간은 구조체 n개 분량인데, for 루프는 i값 0부터 n까지 총 n+1번 반복하고 있네요.

좋은 하루 되세요!

kaki2981의 이미지

그 부분도 이상했었네요. 감사합니다!

chanik의 이미지

올려주신 코드 빌드해봐도 오류가 재현이 안 됩니다. 여러 개의 구조체를 한덩어리로 할당해서쓰고 읽다가 해제하는, 문제없는 사용방식같습니다. 포인터연산 대신 배열형식으로 쓰고 있을 뿐이죠.

위에서 지적된 n + 1 --> n 이어야 하는 부분과, 문자열끝의 널문자까지 복사하기 위해 j < strlen(str) --> j <= strlen(str) 이어야 하는 점이 눈에 띄지만, 실행해봐도 free()에서 오류가 생기지는 않았습니다.

뭔가 문제를 겪었기 때문에 질문하신 것일테니, 같은 오류가 재현되는 샘플을 만들어보셔야 문제가 확인되겠습니다.

익명 사용자의 이미지

입력 샘플 중 라인당 256문자 이상이라면, gets()에서 문제가 생깁니다. 일반적으로 gets()는 "절대" 사용하지 말아야 하는 함수입니다.

익명 사용자의 이미지

정말 그렇네요 맨 페이지에도 친절히 설명 되어있네요

GETS(3)                                                                Linux Programmer's Manual                                                                GETS(3)
 
NAME
       gets - get a string from standard input (DEPRECATED)
 
.
.
.
 
 
BUGS
       Never use gets().  Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets()  will  continue
       to store characters past the end of the buffer, it is extremely dangerous to use.  It has been used to break computer security.  Use fgets() instead.
 
 
.
.
.

댓글 달기

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