I need to write to shared memory, thus I have
我需要写共享内存,因此我有
#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!
}
it throws me exception in strcat
, and if I delete it the exception is thrown in the next line of strcpy
. I need to write to the memory "b34\0
" (4 chars) and then read it.
它在strcat中抛出异常,如果我删除它,则会在strcpy的下一行抛出异常。我需要写入内存“b34 \ 0”(4个字符)然后读取它。
2 个解决方案
#1
6
This:
这个:
strcat(userInput, '\0'); //THROWS EXCEPTION!!
Is not valid C, and it doesn't "throw an exception" because C doesn't have exceptions. Maybe it crashes, but anyway that should be expected since you're not even writing valid code. Use a compiler that rejects obvious invalid code like this.
是无效的C,它不会“抛出异常”,因为C没有异常。也许它会崩溃,但无论如何都应该预料到,因为你甚至没有编写有效的代码。使用拒绝明显无效代码的编译器。
Edit: and this:
编辑:和:
char* userInput = malloc(5);
read(0, userInput, 3);
strcpy(shmaddr,userInput);
Is invalid because you read three characters, leaving the last two characters in userInput
uninitialized, then you call strcpy()
which reads a null terminated string from userInput
, but you have not null-terminated the string, so it is undefined behavior and anything could happen--including a crash. So try this:
是无效的,因为你读了三个字符,留下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);
Or better yet:
或者更好的是:
read(STDIN_FILENO, shmaddr, INPUT_MAX_SIZE);
That is, just read directly to the destination, not a temporary buffer.
也就是说,只需直接读取目标,而不是临时缓冲区。
#2
1
Both the function strcat
and strcpy
expect the arguments to be null-terminated strings, in you case, neither userInput
or shmaddr
satisfies this condition, that's why you see the program crashes. Try this:
函数strcat和strcpy都希望参数是以null结尾的字符串,在你的情况下,userInput或shmaddr都不满足这个条件,这就是你看到程序崩溃的原因。尝试这个:
#define FLAGS IPC_CREAT | 0644
int main(void) {
key = ftok("ex31.c", 'k');
shmid = shmget(key, 4, FLAGS); // the buffer needs at least size 4 to hold the 3 char string and the null terminator
shmaddr = shmat(shmid, 0, 0);
char* userInput = malloc(5);
read(0, userInput, 3);
userInput[3] = '\0';
strcpy(shmaddr, userInput);
}
#1
6
This:
这个:
strcat(userInput, '\0'); //THROWS EXCEPTION!!
Is not valid C, and it doesn't "throw an exception" because C doesn't have exceptions. Maybe it crashes, but anyway that should be expected since you're not even writing valid code. Use a compiler that rejects obvious invalid code like this.
是无效的C,它不会“抛出异常”,因为C没有异常。也许它会崩溃,但无论如何都应该预料到,因为你甚至没有编写有效的代码。使用拒绝明显无效代码的编译器。
Edit: and this:
编辑:和:
char* userInput = malloc(5);
read(0, userInput, 3);
strcpy(shmaddr,userInput);
Is invalid because you read three characters, leaving the last two characters in userInput
uninitialized, then you call strcpy()
which reads a null terminated string from userInput
, but you have not null-terminated the string, so it is undefined behavior and anything could happen--including a crash. So try this:
是无效的,因为你读了三个字符,留下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);
Or better yet:
或者更好的是:
read(STDIN_FILENO, shmaddr, INPUT_MAX_SIZE);
That is, just read directly to the destination, not a temporary buffer.
也就是说,只需直接读取目标,而不是临时缓冲区。
#2
1
Both the function strcat
and strcpy
expect the arguments to be null-terminated strings, in you case, neither userInput
or shmaddr
satisfies this condition, that's why you see the program crashes. Try this:
函数strcat和strcpy都希望参数是以null结尾的字符串,在你的情况下,userInput或shmaddr都不满足这个条件,这就是你看到程序崩溃的原因。尝试这个:
#define FLAGS IPC_CREAT | 0644
int main(void) {
key = ftok("ex31.c", 'k');
shmid = shmget(key, 4, FLAGS); // the buffer needs at least size 4 to hold the 3 char string and the null terminator
shmaddr = shmat(shmid, 0, 0);
char* userInput = malloc(5);
read(0, userInput, 3);
userInput[3] = '\0';
strcpy(shmaddr, userInput);
}