предотвратить повреждение данных при печати массивов символов из массивов элементов структуры в C - PullRequest
0 голосов
/ 26 октября 2011

У меня какая-то странная ошибка, когда члены массива lastName и phoneNumber char структуры struct phoneEntry перезаписываются при попытке печати. Следующий код - это кусочки кода, которые относятся к основной части, которая выделяется.

typedef struct
{
    char firstName[30];
    char lastName[30];
    char phoneNumber[30];
} phoneEntry;

size_t phoneBookSize = 1;
phoneEntry* ptrPhoneBook = malloc(phoneBookSize * sizeof(phoneEntry));


FILE *loadedFile;
char fileName[30];
scanf("%s", fileName);
loadedFile = fopen(fileName, "w"); // ERROR OCCURS

fprintf(loadedFile, "First name\tLast name\tPhone Number\n");
int count = 0;
for (count = 0; count < phoneBookSize - 1; count++)
{
    printf("saving %s %s %s\n", ptrPhoneBook[count].firstName, ptrPhoneBook[count].lastName, ptrPhoneBook[count].phoneNumber);
    fprintf(loadedFile, "%s\t%s\t%s\t\n", ptrPhoneBook[count].firstName, ptrPhoneBook[count].lastName, ptrPhoneBook[count].phoneNumber);
}
fclose(loadedFile);

В основном, данные, хранящиеся в каждом символьном массиве в элементе struct, определены и существуют до инициализации «loadedFile ». В этот момент данные, хранящиеся в элементах массива lastname и charNumber в ptrPhoneBook с индексом 0, перезаписываются ни с чем или просто стираются.

Это вывод:

First name  Last name   Phone Number
James   

В отличие от ожидаемого результата:

First name  Last name       Phone Number
James       Bond            007

Я могу избежать всей проблемы, просто начав счет ptrPhoneBook с 1, а не с 0, но я хочу знать, почему fopen повреждает эти элементы данных с индексом 0.

Код, который я дал, вероятно, не даст вам точного вывода, но ошибка все еще существует.

Если вы хотите попробовать и запустить код самостоятельно, вот код, который вы можете запустить прямо из рук в руки.

// Including libraries into the source code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
    char firstName[30];
    char lastName[30];
    char phoneNumber[30];
} phoneEntry;

main()
{

    size_t phoneBookSize = 1;
    phoneEntry* ptrPhoneBook = malloc(phoneBookSize * sizeof(phoneEntry));

    phoneBookSize++;
    phoneEntry* reallocPhoneBook = realloc(ptrPhoneBook, phoneBookSize);

    if (reallocPhoneBook) {
        ptrPhoneBook = reallocPhoneBook;
    } else {
        printf("Failure. Memory error.\n\n");
    }

    strcpy(ptrPhoneBook[0].firstName, "James");
    strcpy(ptrPhoneBook[0].lastName, "Kim");
    strcpy(ptrPhoneBook[0].phoneNumber, "2343");


    FILE *loadedFile;
    char fileName[30];
    scanf("%s", fileName);
    loadedFile = fopen(fileName, "w");

    fprintf(loadedFile, "First name\tLast name\tPhone Number\n");
    int count = 0;
    for (count = 0; count < phoneBookSize - 1; count++)
    {
        printf("saving %s %s %s\n", ptrPhoneBook[count].firstName, ptrPhoneBook[count].lastName, ptrPhoneBook[count].phoneNumber);
        fprintf(loadedFile, "%s\t%s\t%s\t\n", ptrPhoneBook[count].firstName, ptrPhoneBook[count].lastName, ptrPhoneBook[count].phoneNumber);
    }
    fclose(loadedFile);
}

Вывод кода выше:

First name  Last name   Phone Number
James   2343    

Ответы [ 2 ]

2 голосов
/ 26 октября 2011

realloc является полностью поддельным, поскольку выделяет 2 байта вместо 2 телефонных записей :

size_t phoneBookSize = 1;
/* ... */
phoneBookSize++;
phoneEntry* reallocPhoneBook = realloc(ptrPhoneBook, phoneBookSize);

/* ... */
ptrPhoneBook = reallocPhoneBook;

Вы, вероятно, имели в виду:

realloc(ptrPhoneBook, phoneBookSize * sizeof(phoneEntry))
0 голосов
/ 27 октября 2011

+ 1 для ответа cnicutar - realloc выглядит как проблема 1.

Однако ваш цикл for также неверен: вы выполняете цикл, пока count < phoneBookSize - 1 пропускает последнюю запись - измените ее на count < phoneBookSize, например. если phoneBookSize равен 3, вы должны перейти к индексу массива [2]

...