2013-06-10 2 views
0

이것은 클래스 프로젝트에서 제공됩니다. 문제는 너무 오래 지속될 수도 있지만 문제가 정확히 어디에서 발생할지 모르기 때문에 전체를 끌어내는 것이 유용 할 수 있습니다.malloc, calloc 및 동적 배열

typedef struct 
{ 
    char *name; 
    char **friends; 
    int numFriends; 
} User; 

우리가 구조에 대한 약간의 용기가 :

typedef struct 
{ 
    User *users; 
    int db_size; 
} DB; 

우리는 또한 관리하는 친구를 위해 두 가지 기능을 가지고 :

void makeFriends(char *name1, char *name2, DB *db) 
{ 
    User user1 = findByName(name1); 
    User user2 = findByName(name2); 

    user1.friends[numFriends] = name2; 
    user2.friends[numFriends] = name1; 

    user1.numFriends++; 
    user2.numFriends++; 

    update_db(user1, db); 
    update_db(user2, db); 
} 

void unmakeFriends(char *name1, char *name2, DB *db) 
{ 
    User user1 = getByName(name1); 
    User user2 = getByName(name2); 

    for (int i = 0; i < user1.numFriends; ++i) 
    { 
     if (strcmp(user1.friends[i]), name2) 
     { 
      int size = 0; 
      char *newFriendList = malloc(APPROPRIATE_AMOUNT); 


      for (int j = 0; j < count; ++i) 
      { 
       if (j != i) 
       { 
        newFriendList[size] = user1.friends[j]; 
        size++; 
       } 
      } 

      user1.friends = newFriendList; 
      user1.numFriends = size; 

      // this breaks things for some reason 
      //free(newFriendList); 
     } 
    } 

    // and the same for user2 

    for (int i = 0; i < user2.numFriends; ++i) 
    { 
     if (strcmp(user2.friends[i]), name2) 
     { 
      int size = 0; 

      // this can lead to the corruption of user1's list 
      // char *newFriendList = malloc(APPROPRIATE_AMOUNT); 
      // but this works fine 
      char *newFriendList = calloc(someNum, APPROPRIATE_AMOUNT); 


      for (int j = 0; j < count; ++i) 
      { 
       if (j != i) 
       { 
        newFriendList[size] = user2.friends[j]; 
        size++; 
       } 
      } 

      user2.friends = newFriendList; 
      user2.numFriends = size; 

      // this breaks things for some reason 
      //free(newFriendList); 
     } 
    } 

    update_db(user1, db); 
    update_db(user2, db); 
} 

의 우리가 형태의 구조를 가지고 있다고 가정 해 봅시다

우리는 세 명의 사용자를 만들고 이름을 부여하고 친구 목록에 메모리를 할당합니다.

User vladimir = { .name = "Vladimir", .friends = malloc(APPROPRIATE_AMOUNT), 0 }; 
User estragon = { .name = "Estragon", .friends = malloc(APPROPRIATE_AMOUNT), 0 }; 
User pozzo = { .name = "Pozzo", .friends = malloc(APPROPRIATE_AMOUNT), 0}; 

이제 블라디미르와 에스트라공이 친구가되고 싶어하고, 에스트라공과 포조가 친구가되고 싶다고합시다. 시간이 지나면 블라디미르와 에스트라공은 서로를별로 좋아하지 않으므로 다른 한 사람과 친하게 지내지 않습니다. 나는 기능 unmakeFriends을 실행하고 두 번 malloc를 사용하는 경우

, 친구의 사용자의 목록 두 번째 루프시 (2 회 나오는 이름이나 다른 정의되지 않은 동작 등)이 손상된다. 내가 두 번 calloc을 사용하면, 나는 그 또는 버스 오류를 얻는다. 메모리를 확보하려고하면 버스 오류가 발생합니다. 코드를 사용하는 방식이 현재는 malloc이고, 다른 하나는 calloc입니다. 의도 한대로 작동합니다.

무슨 일이 일어 났으며 그 이유는 무엇입니까?

+0

친구 목록을 만들어 친구 목록을 만들어야합니다. 목록의 각 항목에는 자체 메모리가 할당/해제되고 다른 항목은 그대로 있습니다. 구글 "링크드리스트 C 튜토리얼". – Floris

답변

0

calloc 0은 동적으로 할당하는 버퍼를 초기화합니다. malloc은 단지 그것을 쓰레기로 남겨 둡니다.