Ошибка сегментации при распределении разделяемой памяти между переменными разных типов - PullRequest
0 голосов
/ 11 апреля 2019

Я пытаюсь разделить память между процессами для «эффективного» подсчета повторений строк, поступающих из файла со случайным количеством строк. Итак, допустим, что я получил все из них в char ** words , и я хочу иметь две переменные разных типов для совместного использования ( WordStruct shared и int shared_length ), первая ссылается на структуру, которая имеет позицию строки в словах и ее вхождение, а вторая ссылается на количество строк, которые отличаются. Это потому, что я хочу перебрать shared и знать, когда остановиться, однако проблема возникает, когда я пытаюсь установить значение shared_length .

Это мой код:

typedef struct wordSturct {
    int word_id;
    int count;
} WordStruct;

/* open file */
int index = 0;
char* word = malloc(sizeof(char) * 257);
char** words = malloc(sizeof(char*) * buffer)  /* lets say buffer is way to big */
while (fscanf(fp, "%s", word) == 1) {  /* fp is a FILE* */
    words[index] = malloc(sizeof(char) * 257);
    strcpy(words[index], word);
    index++;
}

key_t key = ftok("/tmp", 'F');
int identifier = shmget(key, sizeof(WordStruct) * index + sizeof(int), IPC_CREAT | SHM_W | SHM_R);
void* shared_memory = shmat(identifier, NULL, 0);
WordStruct* shared = (WordStruct *) shared_memory;
int* shared_length = (int *) (shared + sizeof(WordStruct) * index);

С этого момента я добавляю некоторый тестовый код, чтобы убедиться в правильной функциональности сегмента разделяемой памяти, поэтому давайте подумаем, что повторяющихся слов нет, поэтому итерация с shared до Индекс будет правильным:

for (int i=0; i < index; i++) {
    shared[i].word_id = i;
    shared[i].count = 0;
}

До этого момента все принимается и корректно создается, но затем я пытаюсь сделать это:

*shared_length = 0;  /* main.c:125 */

И я получил следующую ошибку согласно VALGRIND:

Неверная запись размера 4

при 0x400F11: основной (main.c: 125)
Адрес 0x40d1400 не является стековым, malloc или (недавно) свободным

Процесс завершается с действием по умолчанию сигнала 11 (SIGSEGV)

Доступ не в сопоставленной области по адресу 0x40D1400
в 0x400F11: основной (main.c: 125)
...

Ошибка сегментации (ядро сброшено)

Я пытался установить WrapperStruct для назначения функции shmat (), чтобы у меня была только одна структура, но мне нужно знать значение index , прежде чем даже открыть файл, чтобы иметь мой набор слов, так что это не вариант, я думаю.

1 Ответ

2 голосов
/ 11 апреля 2019

Когда вы выполняете арифметику с указателями, она выполняется в единицах размера объекта, на который указывает указатель.Поэтому вам не нужно умножать на sizeof(WordStruct) - это привело к тому, что оно умножилось вдвое, и вы выходите за пределы общей памяти.Должно быть:

int* shared_length = (int *) (shared + index);

или

int *shared_length = (int *)&shared[index];
...