Странная ошибка с realloc в VS 2010 - PullRequest
1 голос
/ 14 мая 2011

У меня есть код:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

typedef struct NOTE
{
    char NAME[50],  
         TELE[30];  
    int  BDAY[3];   
} NOTE;

void AddNote(NOTE * Notes, int NotesCount, NOTE * Temp)
{
    Notes = (struct NOTE *) realloc(Notes, (NotesCount + 1) * sizeof(struct NOTE));
    memcpy(Notes + NotesCount, Temp, sizeof(struct NOTE));
}

void main()
{
    int NotesCount = 0, i = 0, f = 0;
    int a;
    NOTE * BLOC_NOTE, * Temp;

    Temp = (struct NOTE *) malloc(sizeof(struct NOTE));
    BLOC_NOTE = (struct NOTE *) calloc(0, sizeof(struct NOTE));

    for(i = 0; i < 4; i++)
    {
        ShowInputDialog(Temp);
        AddNote(BLOC_NOTE, NotesCount++, Temp);     
    }
}

В третьем элементе BLOC_NOTE происходит сбой программы при

Notes = (struct NOTE *) realloc(Notes, (NotesCount + 1) * sizeof(struct NOTE));

VS говорит мне, что ОС Windows инициировала точку останова ...

Что не так?

Редактировать
Перемещаем код сюда из комментария

void ShowInputDialog(NOTE * Temp) 
{ 
    printf("Name: "); 
    scanf("%s", (*Temp).NAME); 
    printf("Telephone: "); 
    scanf("%s", (*Temp).TELE); 
    printf("Birthday: "); 
    scanf("%d\.%d\.\%d", (*Temp).BDAY, ((*Temp).BDAY + 1), ((*Temp).BDAY + 2));
 }

Ответы [ 3 ]

2 голосов
/ 14 мая 2011

Это неверно:

void AddNote(NOTE * Notes, int NotesCount, NOTE * Temp)
{
    Notes = (struct NOTE *) realloc(Notes, (NotesCount + 1) * sizeof(struct NOTE));
    memcpy(Notes + NotesCount, Temp, sizeof(struct NOTE));
}

Заметки - это локальная переменная, которая содержит адрес вашего первого NOTE объекта.Но когда функция возвращается, это значение теряется.Вы должны вернуть новое значение, так как C не имеет ссылок:

NOTE* AddNote(NOTE * Notes, int NotesCount, NOTE * Temp)
{
    Notes = (struct NOTE *) realloc(Notes, (NotesCount + 1) * sizeof(struct NOTE));
    memcpy(Notes + NotesCount, Temp, sizeof(struct NOTE));
    return Notes;
}

for(i = 0; i < 4; i++)
{
   ShowInputDialog(Temp);
   BLOC_NOTE = AddNote(BLOC_NOTE, NotesCount++, Temp);     
}

В C ++ этого было бы достаточно:

void AddNote(NOTE * &Notes, int NotesCount, NOTE * Temp)
{
    Notes = (struct NOTE *) realloc(Notes, (NotesCount + 1) * sizeof(struct NOTE));
    memcpy(Notes + NotesCount, Temp, sizeof(struct NOTE));
}
2 голосов
/ 14 мая 2011

Хорошо, теперь я понял это.

void AddNote(NOTE * Notes, int NotesCount, NOTE * Temp)
{
    Notes = (struct NOTE *) realloc(Notes, (NotesCount + 1) * sizeof(struct NOTE));
    memcpy(Notes + NotesCount, Temp, sizeof(struct NOTE));
}

В AddNote параметр Notes является копией BLOC_NOTE.Если realloc преуспевает в расширении блока, это нормально.Однако, если realloc выделяет новый блок (и копирует все туда), BLOC_NOTE внезапно становится недопустимым, поскольку теперь он указывает на освобожденную память.

При следующем вызове AddNode отладчик памяти явно обнаруживает это.*

0 голосов
/ 14 мая 2011

Вы требуется для проверки значений указателей, возвращаемых функциями malloc (), calloc () и realloc ().Где вы сделали эти проверки?

...