首页 > 解决方案 > 在不同类型的变量之间分配共享内存时出现分段错误

问题描述

我试图在进程之间共享内存以“有效地”计算来自具有随机字符串数的文件的字符串重复。所以,假设我把它们全部放在char** 单词中,并且我想要共享两个不同类型的变量(WordStruct sharedint 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 (main.c:125)
地址 0x40d1400 没有被堆栈、malloc 或(最近)释放

进程以信号 11 (SIGSEGV) 的默认操作终止

访问不在地址 0x40D1400
处 0x400F11 的映射区域内:main (main.c:125)
...

分段错误(核心转储)

我试图设置一个 WrapperStruct 来分配 shmat() 函数,这样我就可以只有一个结构,但是在打开文件之前我需要知道索引值以获得我的单词数组,所以这不是我认为的选项。

标签: carraysshared-memorysizeof

解决方案


当您对指针进行算术运算时,它是以指针指向的对象的大小为单位执行的。所以你不需要乘以sizeof(WordStruct)- 这导致它被乘以两次,并且你将超出共享内存。它应该是:

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

或者

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

推荐阅读