在不同类型的变量之间分配共享内存时出现分段错误
Segmentation fault when asigning shared memory between variables of different types
我正在尝试在进程之间共享内存,以“有效地”计算来自具有随机字符串数的文件的字符串重复。所以,假设我在 char** words 中得到了所有这些并且我想要共享两个不同类型的变量(WordStruct shared和 int shared_length), 第一个引用了一个结构,该结构具有字符串在 words 中的位置并且它出现了,而第二个引用了不同的字符串数量。这是因为我想迭代 shared 并知道何时停止,但是,当我尝试设置 shared_length[=41= 时出现问题] 到一个值。
这是我的代码:
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 直到 index 是正确的:
for (int i=0; i < index; i++) {
shared[i].word_id = i;
shared[i].count = 0;
}
直到这里,一切都被接受并正确实例化,但后来我尝试这样做:
*shared_length = 0; /* main.c:125 */
根据 VALGRIND,我得到了以下错误:
Invalid write of size 4
at 0x400F11: main (main.c:125)
Address 0x40d1400 is not stack'd, malloc'd or (recently) free'd
进程以信号 11 (SIGSEGV) 的默认操作终止
Access not within mapped region at address 0x40D1400
at 0x400F11: main (main.c:125)
...
分段错误(核心已转储)
我尝试设置一个 WrapperStruct 来分配 shmat() 函数,这样我只能有一个结构,但我需要知道 index 值甚至打开文件以获得我的单词数组,所以我认为这不是一个选项。
当你对指针进行运算时,它是以指针指向的对象的大小为单位执行的。所以你不需要乘以 sizeof(WordStruct)
——这导致它被乘以两次,你就在共享内存之外了。应该是:
int* shared_length = (int *) (shared + index);
或
int *shared_length = (int *)&shared[index];
我正在尝试在进程之间共享内存,以“有效地”计算来自具有随机字符串数的文件的字符串重复。所以,假设我在 char** words 中得到了所有这些并且我想要共享两个不同类型的变量(WordStruct shared和 int shared_length), 第一个引用了一个结构,该结构具有字符串在 words 中的位置并且它出现了,而第二个引用了不同的字符串数量。这是因为我想迭代 shared 并知道何时停止,但是,当我尝试设置 shared_length[=41= 时出现问题] 到一个值。
这是我的代码:
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 直到 index 是正确的:
for (int i=0; i < index; i++) {
shared[i].word_id = i;
shared[i].count = 0;
}
直到这里,一切都被接受并正确实例化,但后来我尝试这样做:
*shared_length = 0; /* main.c:125 */
根据 VALGRIND,我得到了以下错误:
Invalid write of size 4
at 0x400F11: main (main.c:125)
Address 0x40d1400 is not stack'd, malloc'd or (recently) free'd进程以信号 11 (SIGSEGV) 的默认操作终止
Access not within mapped region at address 0x40D1400
at 0x400F11: main (main.c:125)
...分段错误(核心已转储)
我尝试设置一个 WrapperStruct 来分配 shmat() 函数,这样我只能有一个结构,但我需要知道 index 值甚至打开文件以获得我的单词数组,所以我认为这不是一个选项。
当你对指针进行运算时,它是以指针指向的对象的大小为单位执行的。所以你不需要乘以 sizeof(WordStruct)
——这导致它被乘以两次,你就在共享内存之外了。应该是:
int* shared_length = (int *) (shared + index);
或
int *shared_length = (int *)&shared[index];