[英]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);
}
該程序引發分段錯誤。 我想讀取一些字節的數據以及寫入一些字節的數據。 我已經寫了上面的代碼,但是它拋出了一個錯誤,作為段錯誤。 請幫助我解決此問題。
已編輯
#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));
}
輸出:
首先,對read()
和write()
掩蓋系統提供的read(2)
和write(2)
例程。 這是一個巨大的錯誤。 (您可以替換系統提供的系統調用的包裝,但你最好確保你做的一樣好工作他們作為編程系統C庫筆者在第一時間做了。您甚至沒有接近到什么系統提供的read(2)
和write(2)
函數都可以。)您的printf(3)
調用將嘗試在內部使用write(2)
來編寫輸出,並找到您的實現。 因為您處理參數的方式與write(2)
實現的方式非常不同,所以它可能會死於memcpy()
調用-您已經取消引用write()
的第一個參數,就好像它是一個指針一樣,但是printf(3)
會使用1
這樣的整數來調用它。 取消引用1
是確定段的可靠方式。
其次,您不能在傳遞給函數的數組中使用sizeof
作為參數。 作為參數傳遞的數組會衰減到指針-您的函數無法確定是使用數組還是字符指針調用了它,並且sizeof
將要計算(在編譯時!) 指針的大小。 差異很大。 在參數中傳遞數組大小,或者使用編譯時#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)
,因此您可以直接使用對象。
我強烈建議您先花Kernighan和Ritchie的C編程語言,然后再花更多的時間在該程序上-嘗試調試該程序以使其成為現實,這將是一種學習C的痛苦緩慢的方法。
在AIUP_read
您不能使用sizeof(data)
! 返回的大小將是指針的大小,而不是其指向的大小。 您必須將數據的長度提供給函數AIUP_read
和AIUP_write
。
您的崩潰是在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);
好的,這里有兩個問題。 首先,您對sizeof
的使用似乎是錯誤的。 在每種情況下,您似乎都在嘗試讀取/寫入和audio_state
結構,因此您應該使用sizeof(audio_state)
復制整個結構。 在32位計算機上, sizeof(data)
可能會給您4,在64位計算機上, sizeof(data)
會給您8,而sizeof(user_mem[pos])
將會是1。
其次,您的printf
語句在一種情況下使用%c
,在另一種情況下使用%s
。 我懷疑出現段錯誤的原因是:
printf("The written data is:%s",*data);
您要讓printf
期待一個字符串(一個char*
),但是您要傳入*data
,它是一個unsigned char
。 printf
將此字符轉換為char*
並嘗試訪問該地址。 由於它不是字符串,因此會出錯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.