[英]seg fault during memcpy()
#include<stdio.h>
#include<string.h>
#define USER_MEM (10*1024)
typedef struct {
unsigned short int vol_level;
int mute_stat;
}audio_state;
static audio_state aud_stat;
static unsigned char user_mem[USER_MEM];
void aud_read(unsigned char * data)
{
unsigned short pos =0;
memcpy(data,&user_mem[pos],sizeof(data));
printf("The Read data is:%c",*data);
}
void aud_write(unsigned char * data)
{
unsigned short pos =0;
memcpy(&user_mem[pos],data,sizeof(user_mem[pos]));
printf("The written data is:%s",*data);
}
int main()
{
aud_stat.vol_level=10;
aud_stat.mute_stat=20;
aud_write((unsigned char*)&aud_stat);
aud_read((unsigned char*)&aud_stat);
}
This program is throwing a segmentation fault. 该程序引发分段错误。 I wanted to read some bytes of data as well as to write some bytes of data.
我想读取一些字节的数据以及写入一些字节的数据。 I have written the above code but it's throwing an error as seg fault.
我已经写了上面的代码,但是它抛出了一个错误,作为段错误。 Please help me to resolve this issue.
请帮助我解决此问题。
EDITED 已编辑
#include<stdio.h>
#include<string.h>
#define USER_MEM (10*1024)
typedef struct {
unsigned short int vol_level;
int mute_stat;
}audio_state;
static audio_state aud_stat;
static unsigned char user_mem[USER_MEM];
void read(unsigned char * data,unsigned short num)
{
printf("Into Read!\n");
unsigned short pos =0;
memcpy(data,&user_mem[pos],num);
printf("The Read data is:%c",*data);
}
void write(unsigned char * data,unsigned short num)
{
printf("Into Write!\n");
unsigned short pos =0;
memcpy(&user_mem[pos],data,num);
printf("The written data is:%c",*data);
}
int main()
{
aud_stat.vol_level=10;
aud_stat.mute_stat=20;
write((unsigned char*)&aud_stat,sizeof(audio_state));
read((unsigned char*)&aud_stat,sizeof(audio_state));
}
output: 输出:
First, your use of read()
and write()
shadows the system-supplied read(2)
and write(2)
routines. 首先,对
read()
和write()
掩盖系统提供的read(2)
和write(2)
例程。 This is a giant mistake. 这是一个巨大的错误。 (You can replace the system-supplied system call wrappers but you had better make sure you do as good a job programming them as the system C library authors did in the first place. Yours aren't even close to what the system-supplied
read(2)
and write(2)
functions do.) Your printf(3)
call will try to use write(2)
internally to write your output and will find your implementation instead. (您可以替换系统提供的系统调用的包装,但你最好确保你做的一样好工作他们作为编程系统C库笔者在第一时间做了。您甚至没有接近到什么系统提供的
read(2)
和write(2)
函数都可以。)您的printf(3)
调用将尝试在内部使用write(2)
来编写输出,并找到您的实现。 Because yours handles its parameters very differently than the write(2)
implementation, it'll probably die on that memcpy()
call -- you've dereferenced the first argument to write()
as if it were a pointer, but printf(3)
will call it with an integer like 1
. 因为您处理参数的方式与
write(2)
实现的方式非常不同,所以它可能会死于memcpy()
调用-您已经取消引用write()
的第一个参数,就好像它是一个指针一样,但是printf(3)
会使用1
这样的整数来调用它。 Dereferencing 1
is a sure-fire way to segfault. 取消引用
1
是确定段的可靠方式。
Second, you cannot use sizeof
on an array passed into a function as a parameter. 其次,您不能在传递给函数的数组中使用
sizeof
作为参数。 Arrays passed as parameters decay to pointers -- your function cannot determine if it was called with an array or a character pointer, and sizeof
is going to calculate (at compile time!) the size of a pointer . 作为参数传递的数组会衰减到指针-您的函数无法确定是使用数组还是字符指针调用了它,并且
sizeof
将要计算(在编译时!) 指针的大小。 Huge difference. 差异很大。 Either pass array sizes in the parameters or use compile-time
#defines
to make them the same across the whole project. 在参数中传递数组大小,或者使用编译时
#defines
在整个项目中使它们相同。
Third: 第三:
void write(unsigned char * data) /* .... */ printf("The written data is:%s",*data);
This has the effect of passing a single character to printf(3)
but your format string suggested you were going to pass a "string". 这具有将单个字符传递给
printf(3)
的效果,但是格式字符串建议您将要传递“字符串”。 C strings are NUL
-terminated char
arrays -- who knows when the next '\\0'
byte in the input you've given it is going to come. C字符串是
NUL
终止的char
数组-谁知道您输入中的下一个'\\0'
字节何时到达。
Fourth: 第四:
void write(unsigned char * data) /* ... */ aud_stat.mute_stat=20; write((unsigned char*)&aud_stat);
You're making dangerous (and needless) casts away from your structure type to a completely unrelated type. 您正在将危险的(且不必要的)强制转换从结构类型转换为完全不相关的类型。 Your new
write()
replacement should look something more like void write_aud(audio_state *a)
, so you can work with your objects directly. 新的
write()
替换看起来应该更像是void write_aud(audio_state *a)
,因此您可以直接使用对象。
I strongly recommend reading The C Programming Language by Kernighan and Ritchie before spending much more time on this program -- trying to debug this one into existence is going be a painfully slow way to learn C. 我强烈建议您先花Kernighan和Ritchie的C编程语言,然后再花更多的时间在该程序上-尝试调试该程序以使其成为现实,这将是一种学习C的痛苦缓慢的方法。
In AIUP_read
you can not use sizeof(data)
! 在
AIUP_read
您不能使用sizeof(data)
! The size returned will be that of the pointer , not what it points to. 返回的大小将是指针的大小,而不是其指向的大小。 You must supply the length of data to the functions
AIUP_read
and AIUP_write
. 您必须将数据的长度提供给函数
AIUP_read
和AIUP_write
。
Your crash is in AIUP_write
: 您的崩溃是在
AIUP_write
:
printf("The written data is:%s",*data);
you are attempting to read a string, thus crashing (change to '%d' to print the value of vol_level
). 您正在尝试读取字符串,从而崩溃(更改为'%d'以显示
vol_level
的值)。
There are other logic issues, related to the use of sizeof and the use of pos
, which is always 0. 还有其他逻辑问题,与使用sizeof和
pos
(始终为0)有关。
A debugger shows these problems quite easily: 调试器很容易显示这些问题:
(gdb) r
Starting program: /private/tmp/a.out
Reading symbols for shared libraries +........................ done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
0x00007fff8e22e4f0 in strlen ()
(gdb) bt
#0 0x00007fff8e22e4f0 in strlen ()
#1 0x00007fff8e1cf8c3 in __vfprintf ()
#2 0x00007fff8e1ce18e in vfprintf_l ()
#3 0x00007fff8e1d72d0 in printf ()
#4 0x0000000100000e12 in write (data=0x100003880 "\n") at test2.c:26
#5 0x0000000100000e4e in main () at test2.c:33
(gdb) list 26,26
26 printf("The written data is:%s",*data);
Ok, there's a couple of problems here. 好的,这里有两个问题。 First, your use of
sizeof
seems to be wrong. 首先,您对
sizeof
的使用似乎是错误的。 In each case it looks like you're trying to read/write and audio_state
structure, so you should be using sizeof(audio_state)
to copy the entire structure. 在每种情况下,您似乎都在尝试读取/写入和
audio_state
结构,因此您应该使用sizeof(audio_state)
复制整个结构。 sizeof(data)
will probably give you 4 on a 32bit machine and 8 on a 64bit machine, while sizeof(user_mem[pos])
is going to be 1. 在32位计算机上,
sizeof(data)
可能会给您4,在64位计算机上, sizeof(data)
会给您8,而sizeof(user_mem[pos])
将会是1。
Secondly, your printf
statements are using %c
in one case and %s
in another. 其次,您的
printf
语句在一种情况下使用%c
,在另一种情况下使用%s
。 I suspect the reason for the seg-fault is the line: 我怀疑出现段错误的原因是:
printf("The written data is:%s",*data);
You're telling printf
to expect a string (a char*
) but you're passing in *data
which is an unsigned char
. 您要让
printf
期待一个字符串(一个char*
),但是您要传入*data
,它是一个unsigned char
。 printf
will cast this char to a char*
and try to access the address. printf
将此字符转换为char*
并尝试访问该地址。 Since it's not a string it's going to fault. 由于它不是字符串,因此会出错。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.