2011-11-11 23 views
-1
#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 faultとしてエラーを投げている。この問題を解決するのを手伝ってください。memcpy()中の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)); 
} 

出力:あなたはsizeof(data)を使用することはできませんAIUP_read

+0

を学ぶための痛々しいほど遅い方法が起こっているあなたは、デバッガを通してそれを実行したのを? 'memcpy'に与えられたポインタが有効であることを確認しましたか? –

+0

私はcodepadを使用しています。私はCソフトウェアをインストールしていません。 – Angus

+0

@Angus:1つ手に入れることをお勧めします。 – leppie

答えて

3

最初に、read()write()を使用すると、システム提供のread(2)write(2)ルーチンがシャドーされます。これは巨大な間違いです。 (あなたはシステムが提供するシステムコールのラッパーを置き換えることができますが、あなたが最初の場所で行ったシステムのCライブラリの作者としてそれらをプログラミングするとして良い仕事をすることを確認したほうが良い。ユアーズでも近いものにはありませんシステムが提供するread(2)write(2)機能を行う。)あなたのprintf(3)呼び出しは、あなたの出力を書き込むために内部write(2)を使用しようとすると、代わりにあなたの実装を見つけるでしょう。あなたのパラメータはwrite(2)の実装とはまったく異なっているため、memcpy()の呼び出しではおそらく最初の引数がwrite()に逆参照されていますが、printf(3)1のような整数で呼び出されます。 Dereferencing 1はsegfaultへの確実な方法です。

第2に、関数にパラメータとして渡された配列に対してsizeofを使用することはできません。パラメータとして渡された配列がポインタに崩壊する - 関数は配列か文字ポインタで呼び出されたかどうかを調べることができません。sizeofポインタのサイズを(コンパイル時に)計算しようとしています。大きな違い。配列サイズをパラメータに渡すか、コンパイル時に#definesを使用して、プロジェクト全体で同じサイズにします。

サード:

void write(unsigned char * data) 
/* .... */ 
printf("The written data is:%s",*data); 

これはprintf(3)単一の文字を渡すの効果がありますが、あなたのフォーマット文字列を使用すると、「文字列」を渡すつもりだったが示唆されました。 Cの文字列はNUL -terminated 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

!返されるサイズは、それが何を指すポインタ、ではないのだろう。あなたは機能AIUP_readAIUP_writeへのデータの長さを指定する必要があります。

+0

私はstrlen(data)とstrlen(user_mem [pos])をやっています。これは正しいです.Plsヘルプ – Angus

1

あなたのクラッシュはAIUP_writeである:あなたがこれ(vol_levelの値を印刷するには「%D」への変更を)クラッシュ、文字列を読み込むしようとしている

printf("The written data is:%s",*data); 

常に0

デバッガでのsizeofの使用とposの使用に関連する他のロジックの問題が、ありますが、非常に簡単にこれらの問題を示しています

(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); 
1

[OK]を、がありますここの問題のカップル。まず、sizeofの使用が間違っているようです。それぞれのケースで、それはあなたが/書き込みとaudio_state構造を読み取ろうとしているので、あなたは、全体の構造をコピーするsizeof(audio_state)を使用する必要があるように見えます。 sizeof(user_mem[pos])は、あなたのprintf文は、別の1つのケースで%c%sを使用している第二に1

あることを行っている間、sizeof(data)は、おそらく、64ビットマシン上で32ビットマシンと8の上に、あなたに4を与えるだろう。

printf("The written data is:%s",*data);

あなたは、文字列(char*を)期待するprintfを言っているが、あなたはunsigned charある*dataに渡している:私は、ワンセグ障害の理由がラインである疑いがあります。 printfchar*にこの文字をキャストして、アドレスにアクセスしようとします。それは文字列ではないので、それは失敗するだろう。

+0

ショーン:あなたは正しい!私は間違いがない。しかし出力は印刷できませんでした。編集を参照してください – Angus

+0

私は間違いがどこにあるのか識別するのを助けてください! – Angus

関連する問題