我在两个不同进程之间交换消息时遇到了问题。 我必须只使用动态数组。 我也试过使用共享内存,但我还没有解决我的问题。
这是发件人的代码:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#define KEYMSG 12345678
typedef struct msg
{
long int type;
char* str1;
char* str2;
}msg;
int main()
{
msg mymsg;
mymsg.str1=(char*)malloc(30*sizeof(char));
mymsg.str2=(char*)malloc(30*sizeof(char));
strcpy(mymsg.str1,"this is a test ");
strcpy(mymsg.str2,"test ok ");
mymsg.type=1;
if((msgget(KEYMSG,IPC_CREAT|0666))==-1)
{
fprintf(stderr,"ERROR CREATION\n");
fflush(stderr);
}
else
{
fprintf(stdout,"CREATION OK\n-----------\n");
fflush(stdout);
}
if((msgsnd(msgget(KEYMSG,0666),&mymsg,sizeof(msg),IPC_NOWAIT))<0)
{
fprintf(stderr,"msg not sent\n");
fflush(stderr);
}
else
{
fprintf(stdout, "\nmsg sent:\n");
fprintf(stdout, "%s\t%s\n\n",mymsg.str1,mymsg.str2);
fflush(stdout);
}
这是读者的代码:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#include <sys/shm.h>
#define KEYMSG 12345678
typedef struct msg
{
long int type;
char* str1;
char* str2;
}msg;
int main()
{
msg mymsgrcv;
mymsgrcv.str1=(char*)malloc(30*sizeof(char));
mymsgrcv.str2=(char*)malloc(30*sizeof(char));
if((msgrcv(msgget(KEYMSG,0666),&mymsgrcv,sizeof(msg),1,IPC_NOWAIT))==-1)
{
fprintf(stderr,"READ ERROR\n");
fflush(stderr);
}
else
{
fprintf(stdout, "\nmsg read:\n");
fprintf(stdout, "%s\t%s\n\n",mymsgrcv.str1,mymsgrcv.str2);
fflush(stdout);
}
return 0;
}
答案 0 :(得分:2)
1。)在您的消息中,您有指向字符串的指针,但它们的地址只是一个进程的本地地址。地址对其他进程没有意义。 你必须传递字符串,而不仅仅是指向它的指针。
定义消息,例如像这样:
typedef struct msg
{
long int type;
char str1[32];
char str2[32];
}msg;
2。)始终对malloc(3)
返回的指针进行错误检查!
答案 1 :(得分:0)
所以你在Linux下编写了一个软件崩溃的软件。如何找到它?
第一步是在编译器中启用调试信息(gcc中的-g
)。
然后安装valgrind。
现在假设您的程序名为homework
(因此您将其作为./homework
运行),因此请运行:
valgrind homework
和valgrind会告诉你问题所在。
答案 2 :(得分:0)
在 reader 部分中,由于mymsgrcv.str1
和mymsgrcv.str2
可能是空字符串(它们不带结束字符\0
),因此可能会出现堆溢出
您可以使用valgrind或gcc地址清理程序(使用此编译行:gcc -g -Wall -fsanitize=address -fno-omit-frame-pointer reader.c -o reader
)。
以下是gcc地址消毒剂报告的内容:
==22502==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000effe at pc 0x7fca63d99111 bp 0x7fff4ff40520 sp 0x7fff4ff3fcd0
READ of size 31 at 0x60300000effe thread T0
#0 0x7fca63d99110 (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x5e110)
#1 0x7fca63d99a64 in __interceptor_vfprintf (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x5ea64)
#2 0x7fca63d99b69 in __interceptor_fprintf (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x5eb69)
#3 0x400c15 in main /home/jvet/TMP/reader.c:32
#4 0x7fca639b3b44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)
#5 0x400988 (/home/jvet/TMP/reader+0x400988)
0x60300000effe is located 0 bytes to the right of 30-byte region [0x60300000efe0,0x60300000effe)
allocated by thread T0 here:
#0 0x7fca63dcf37a in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9437a)
#1 0x400ad7 in main /home/jvet/TMP/p2.c:21
#2 0x7fca639b3b44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)
答案 3 :(得分:0)
每当你想通过IPC发送字符串时,更喜欢使用数组固定大小,即使你发送的数据非常少,这也会使IPC消息变得更大
要删除此类问题,您可以使用可变大小的数组和消息头后面的数据大小来拖尾数据。