#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);
}
此程序引发了分段错误。我想读取一些字节的数据以及写入一些字节的数据。我已经编写了上面的代码,但它抛出一个错误作为seg错误。请帮我解决这个问题。
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));
}
输出:
答案 0 :(得分:3)
首先,您使用read()
和write()
会影响系统提供的read(2)
和write(2)
例程。这是一个巨大的错误。 (你可以替换系统提供的系统调用包装器,但你最好确保你做的就像系统C库作者首先编写它们一样好。你甚至不是< em>关闭系统提供的read(2)
和write(2)
函数。)您的printf(3)
调用会尝试在内部使用write(2)
来编写输出,会找到你的实现。因为你的参数处理它的参数与write(2)
实现完全不同,它可能会在memcpy()
调用时死掉 - 你已经将write()
的第一个参数解除引用,就好像它是一个指针一样,但是printf(3)
会使用类似1
的整数来调用它。解除引用1
是一种确定的段错误方法。
其次,您不能在传递给函数的数组上使用sizeof
作为参数。作为参数传递的数组衰减为指针 - 您的函数无法确定是否使用数组或字符指针调用它,并且sizeof
将计算(在编译时!)指针的大小< / em>的。巨大的差异。要么在参数中传递数组大小,要么使用编译时#defines
使它们在整个项目中相同。
第三
void write(unsigned char * data) /* .... */ printf("The written data is:%s",*data);
这具有将单个字符传递给printf(3)
的效果,但是您的格式字符串建议您传递“字符串”。 C字符串是NUL
- 终止的char
数组 - 谁知道你给它的输入中的下一个'\0'
字节何时会出现。
第四:
void write(unsigned char * data) /* ... */ aud_stat.mute_stat=20; write((unsigned char*)&aud_stat);
你正在从你的结构类型到完全不相关的类型进行危险(和不必要的)转换。您的新write()
替代品应该更像void write_aud(audio_state *a)
,因此您可以直接使用对象。
我强烈建议在花费更多时间在这个程序之前阅读The C Programming Language by Kernighan and Ritchie - 尝试调试这个程序是一种非常缓慢的学习C的方法。
答案 1 :(得分:1)
在AIUP_read
中,您无法使用sizeof(data)
!返回的大小将是指针的大小,而不是它指向的大小。您必须向函数AIUP_read
和AIUP_write
提供数据长度。
答案 2 :(得分:1)
您的崩溃位于AIUP_write
:
printf("The written data is:%s",*data);
您正在尝试读取字符串,从而崩溃(更改为'%d'以打印vol_level
的值)。
还有其他逻辑问题,与sizeof的使用和pos
的使用有关,它总是为0。
调试器很容易显示这些问题:
(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);
答案 3 :(得分:1)
好的,这里有几个问题。首先,您使用sizeof
似乎是错误的。在每种情况下,您似乎都在尝试读/写和audio_state
结构,因此您应该使用sizeof(audio_state)
来复制整个结构。 sizeof(data)
可能会在32位机器上为4,在64位机器上为8,而sizeof(user_mem[pos])
将为1。
其次,您的printf
语句在一个案例中使用%c
,在另一个案例中使用%s
。我怀疑seg-fault的原因是这一行:
printf("The written data is:%s",*data);
您告诉printf
期待一个字符串(char*
),但您传递的*data
是unsigned char
。 printf
会将此字符转换为char*
并尝试访问该地址。因为它不是一个字符串,所以它会出错。