写入共享内存核心转储分段故障

Zoh*_*gov -2 c malloc coredump shared-memory backslash

我需要写共享内存,因此我有

#define FLAGS IPC_CREAT | 0644
int main() {
key = ftok("ex31.c", 'k');
shmid = shmget(key, 3, FLAGS);
shmaddr = shmat(shmid,0,0);    // THOSE LINES WORK AS EXPECTED

char* userInput = malloc(5);
read(0, userInput, 3);  // I want to read "b34" for example, WORKS GOOD
strcpy(shmaddr,userInput);   // THROWS EXCEPTION!
}
Run Code Online (Sandbox Code Playgroud)

它会抛出异常strcat,如果我删除它,则会在下一行抛出异常strcpy.我需要写入内存" b34\0"(4个字符),然后读取它.

Joh*_*nck 6

这个:

strcat(userInput, '\0');   //THROWS EXCEPTION!!
Run Code Online (Sandbox Code Playgroud)

是无效的C,并且它不会"抛出异常",因为C没有异常.也许它会崩溃,但无论如何都应该预料到,因为你甚至没有编写有效的代码.使用拒绝明显无效代码的编译器.


编辑:和:

char* userInput = malloc(5);
read(0, userInput, 3);
strcpy(shmaddr,userInput);
Run Code Online (Sandbox Code Playgroud)

是无效的,因为你读了三个字符,留下最后两个字符userInput未初始化,然后你调用strcpy()哪个读取空终止字符串userInput,但你没有空终止字符串,所以它是未定义的行为,任何事情都可能发生 - 包括崩溃.试试这个:

const size_t INPUT_MAX_SIZE = 3;
char userInput[INPUT_MAX_SIZE + 1];
read(STDIN_FILENO, userInput, INPUT_MAX_SIZE);
userInput[INPUT_MAX_SIZE] = '\0'; // add null terminator
strcpy(shmaddr,userInput);
Run Code Online (Sandbox Code Playgroud)

或者更好的是:

read(STDIN_FILENO, shmaddr, INPUT_MAX_SIZE);
Run Code Online (Sandbox Code Playgroud)

也就是说,只需直接读取目标,而不是临时缓冲区.