구조체 동적할당 관련 질문입니다!

p952973의 이미지

다음과 같이 st[i]->name = "minwoo"; 이런식으로 설정하면 실행은 되지만 이후에 세그먼테이션 오류가 발생합니다. free 부분에서 발생하는데

strcpy(st[i]->name = "minwoo"; 이렇게 하면 이상없이 실행 되네요 strcpy를 사용해야 하는 이유가 무엇인지 알고 싶습니다.

st[i]->name = "";과 strcpy(st[i]->name,"");에 무슨 차이가 있는걸까요? 도와주세요!

#include
#include
#include
typedef struct {
char* name;
int math, eng;
float ave;
char grade;
}score;

int j=1; // No 표기 위한 전역변수...

void calc_ave(score *st) {
st->ave = (st->math + st->eng)/2.0;
}

void calc_grade(score *st) {
if((st->ave/10.0) > 9.0) st->grade = 'A';
else if((st->ave/10.0) > 8.0) st->grade = 'B';
else st->grade = 'F';
}

void print_result(score *st){
printf("%d %s %d %d %.1f %c\n",j++, st->name, st->math, st->eng, st->ave, st->grade);
}

void change_math(score *st, int num){
st->math = num;
}

void change_eng(score *st, int num){
st->eng = num;
}

void main(void)
{
int i;

score* st[3]; // 포인터 배열을 선언!!

for(i=0;i<3;i++)
{
st[i] = (score *)malloc(sizeof(score));
st[i]->name = (char *)malloc(sizeof(char)*30);
}

st[0]->name = "minwoo1"; st[0]->math=90;st[0]->eng = 88;
st[1]->name = "minwoo2"; st[1]->math=80;st[1]->eng = 77;
st[2]->name = "minwoo3"; st[2]->math=100;st[2]->eng = 87;

//strcpy(st[0]->name,"minwoo1"); st[0]->math=90;st[0]->eng = 88;
//strcpy(st[1]->name,"minwoo2"); st[1]->math=90;st[1]->eng = 88;
//strcpy(st[2]->name,"minwoo3"); st[2]->math=90;st[2]->eng = 88;

calc_ave(st[0]);calc_ave(st[1]);calc_ave(st[2]); // st[0] 자체가 포인터 선언되었기 때문에 &사용하지 않아도 된다. 사용하게 되면
//포인터의 포인터가 되어 오류 난다...
calc_grade(st[0]);calc_grade(st[1]);calc_grade(st[2]);

printf("No name Math English Average Grade\n");
printf("============================================================================\n");
for(i=0;i<3;i++)
{
print_result(st[i]);
}

printf("No name Math English Average Grade\n");
printf("============================================================================\n");

j = 1;
change_math(st[1], 99);
change_eng(st[1], 80);
calc_ave(st[1]);
calc_grade(st[1]);

for(i=0;i<3;i++)
{
print_result(st[i]);
}
free(st[0]->name);free(st[1]->name);free(st[2]->name);
free(st[0]);free(st[1]);free(st[2]);


}

HeroicCharge의 이미지

st[i]->name = "minwoo"; 이거는 st[i]->name 에 malloc으로 할당한 메모리 대신 "minwoo"문자열의 메모리로 교체 하면서 free할때 오류가 나는것이구요.

strcpy는 st[i]->name에 malloc으로 할당된 메모리에다가 "minwoo"라는 값을 복사해서 넣는것이구요.

후자의 방법(strcpy)으로 사용해야 할것 같습니다.

raymundo의 이미지

name 변수에 malloc 에 의해 확보받은 공간의 시작주소가 담겨 있는 상황에서,

strcpy는 "바로 그 주소"에 두번째 인자의 문자열의 내용을 복사합니다.

name = "minwoo1" 이것은 문자열 리터럴 상수가 담겨 있는 영역(그리고 이 공간은 주로 읽기 전용이고)에서 첫 글자 'm'이 있는 주소값을 name 변수에 담게 됩니다.

그리고 free 는 그 주소부터 시작하는 공간을 반납하려고 하는데, 이 주소는 malloc이 반환했던 그 주소가 아니고, 따라서 반납에 실패하고 에러를 내게 됩니다.

P.S. 한발 늦어 뒷북 리플이 되었네요 OTL

좋은 하루 되세요!

p952973의 이미지

두분 덕에 이해가 잘 되었습니다. 또 글올리면 답해주세요:)

주말 잘 보내세요~!!

댓글 달기

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