почему я получаю ошибку сегментации, когда при чтении объектов из файла? [Дубликат]

«Явный» тип в Java - это класс, который является неэквивалентным и имеет дело с «сырыми» объектами, а не с типичными типами типовых параметров.

Например, до того, как были доступны дженерики Java , вы должны использовать класс коллекции следующим образом:

LinkedList list = new LinkedList();
list.add(new MyObject());
MyObject myObject = (MyObject)list.get(0);

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

Используя generics, вы удаляете «неизвестный» коэффициент, потому что вы должны явно указать, какой тип объектов может идти в списке:

LinkedList<MyObject> list = new LinkedList<MyObject>();
list.add(new MyObject());
MyObject myObject = list.get(0);

Обратите внимание, что с помощью дженериков вам не нужно бросать объект, исходящий из вызова get, сбор предварительно задан для работы с MyObject. Этот факт является основным движущим фактором для генериков. Он меняет источник ошибок времени выполнения во что-то, что можно проверить во время компиляции.

0
задан Elfayer 14 November 2013 в 20:04
поделиться

2 ответа

Файл для чтения был открыт только для записи.

Фактический объект std::string не может быть записан таким образом. Фактический объект обычно содержит пару указателей и, возможно, размер, но не фактические данные символов.

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

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <string>
#include <vector>

typedef struct s_test
{
    char cmd[5];
    std::string str;
}t_test;

void Write(int fd, struct s_test* test)
{
    write(fd, test->cmd, sizeof(test->cmd));
    unsigned int sz = test->str.size();
    write(fd, &sz, sizeof(sz));
    write(fd, test->str.c_str(), sz);
}

void Read(int fd, struct s_test* test)
{
    read(fd, test->cmd, sizeof(test->cmd));
    unsigned int sz;
    read(fd, &sz, sizeof(sz));
    std::vector<char> data(sz);
    read(fd, &data[0], sz);
    test->str.assign(data.begin(), data.end());
}

int main()
{
    t_test test;
    int fd = open("test", O_APPEND | O_CREAT | O_TRUNC | O_WRONLY, 0666);

    test.cmd[0] = 's';
    test.cmd[1] = 'm';
    test.cmd[2] = 's';
    test.cmd[3] = 'g';
    test.cmd[4] = 0;
    test.str = "hello world";
    std::cout << "Before Write: " << test.cmd << " " << test.str << std::endl;

    Write(fd, &test);
    close(fd);

    fd = open("test", O_RDONLY, 0666);
    t_test test2;
    Read(fd, &test2);
    std::cout << "After Read: " << test2.cmd << " " << test2.str << std::endl;
    close(fd);

    return (0);
}
1
ответ дан Retired Ninja 21 August 2018 в 00:29
поделиться
  • 1
    Является ли это "двоичным" протокол? – Elfayer 15 November 2013 в 12:14
  • 2
    Да, байты считываются / записываются так же, как и в памяти. Там нет перевода чего-либо, что еще не текст в текст. – Retired Ninja 15 November 2013 в 12:19
  • 3
    Потому что, когда я пишу структуру с char [4] в файле, я открываю этот файл, я могу прочитать строку напрямую. Он не был переведен каким-либо образом в двоичном формате. – Elfayer 19 November 2013 в 17:44
  • 4
    Кажется, ваше понимание двоичного кода неверно. Необработанные байты ascii-текста по-прежнему являются ascii-текстом. – Retired Ninja 20 November 2013 в 00:34

См., когда вы выгружаете структуру в двоичный файл, ее изображение в памяти записывается на диск, например:

class X
{
public:
    int i;
    int j;
};

. , .

X lX;
lX.i= 10;
lX.j = 20;

объект класса lX при записи в двоичный файл будет выглядеть примерно так: | 10 | 20 | i.e, когда вы его прочитаете, он будет работать нормально.

, но для класса, который содержит любой указатель, такой как строка.

class Y
{
public:
    int* pi;
    int j;
};

. , .

Y lY;
lY.pi= new int(10); // lets assume this is created at memory location 1001
lY.j = 20;

, поэтому объект lY будет иметь значение pi как 1001 (не 10, так как это указатель). теперь, когда вы пишете lY в двоичном файле, это будет выглядеть как | 10001 | 20 | и когда вы его прочитаете, он построит новый объект Y (скажем, lY2), имеющий значения pi, равные 1001, а j - 20. Теперь мы указываем на то, что pi (которое является указателем)? ответ - мусор, это то, что вы смотрите на экране. Я думаю, вы используете Windows для запуска этого, так как Linux дал бы вам ошибку сегментации.

0
ответ дан Shubham 21 August 2018 в 00:29
поделиться
  • 1
    Таким образом, вам необходимо сериализовать строку, которая может быть завершена нулем или предшествующей длине. – Shubham 14 November 2013 в 20:44
Другие вопросы по тегам:

Похожие вопросы: