【发布时间】:2015-09-20 02:56:22
【问题描述】:
我正在学习使用 C (linux) 中的共享内存进行编程。我需要在将使用 fork() 创建的几个进程之间共享一些结构。不幸的是,当我尝试初始化新共享的地址空间时,我在 memcpy 调用中收到一个提示错误(控制台中没有输出)。
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#define ROWS 10000
#define COLS 15000
struct mm_shared {
int test;
unsigned char matrix[ROWS][COLS];
};
int main(void) {
int fd;
if ((fd = shm_open("/mm", O_CREAT | O_RDWR, 0777)) == -1) {
printf(stderr, "shm_open failed! %d - %s\n", errno, strerror(errno));
}
if (ftruncate(fd, sizeof(struct mm_shared) == -1)) {
printf(stderr, "ftruncate failed! %d - %s\n", errno, strerror(errno));
}
struct mm_shared * shared;
if ((shared = mmap(NULL, sizeof(struct mm_shared), PROT_READ
| PROT_WRITE, MAP_SHARED, fd, 0)) == -1) {
printf("mmap failed! %d, %s\n", errno, strerror(errno));
}
struct mm_shared * init = (struct mm_shared *) malloc(sizeof(struct mm_shared));
memcpy(shared, init, sizeof(struct mm_shared)); <-- here lies the problem!
shm_unlink("/mm");
return EXIT_SUCCESS;
}
调试共享指针时,调试信息(eclipse调试器)显示:
Failed to execute MI command:
-data-evaluate-expression (shared)->test
Error message from debugger back end:
Cannot access memory at address 0x7ffff7ffc000
我不知道这是否有帮助。另外,我想问一下我在结构中存储大矩阵的方法是否正确(它应该在堆中分配对吗?因为即使矩阵本身不是指针,我也会得到一个指向结构的指针)。
对此的任何帮助将不胜感激!
【问题讨论】:
-
请注意,
malloc()返回的数据未初始化,因此您试图将未初始化的数据复制到共享数据上。就其本身而言,这不应该导致崩溃。您为该结构分配了大约 150 MiB,并且大概有那么多共享内存。您当然应该验证malloc()是否成功,尽管找到失败的台式机会有点令人惊讶。 -
您需要在编译时出现更多警告。您从标题中省略了
<stdio.h>、<stdlib.h>、<unistd.h>和<sys/mman.h>。当它们被提供时,编译器会告诉你你不应该使用printf(stderr, …;大概,你的意思是fprintf(stderr, …。当您通过该批次,并得到shared和-1之间的比较固定(== (void *)-1有效-mmap()返回一个 void 指针),然后代码编译。我得到mmap failed! 22, Invalid argument后跟核心转储,因为代码在失败消息后继续。 -
POSIX.1 说如果发生错误,
mmap()将返回MAP_FAILED(应该 等于(void *)-1)并设置errno。至少,在错误情况下,我希望return EXIT_FAILURE;。此外,虽然从技术上讲,映射的length不需要与sysconf(_SC_PAGESIZE)对齐(向上舍入到下一个倍数),但建议这样做(以避免在内核或C 库中舍入错误)。 -
感谢您的 cmets,他们帮助改进了我的代码。
标签: c shared-memory mmap memcpy