2011-11-11 2 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 오류로 오류가 발생했습니다. 이 문제를 해결하도록 도와주세요.memcpy() 동안 seg 오류

편집
#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)); 
} 

출력 : AIUP_read에서

+0

당신이 디버거를 통해 실행나요 배울 수있는 고통스럽게 느린 방법이 될 것입니다 -

나는 강력하게이 프로그램에 더 많은 시간을 소비하기 전에 The C Programming Language by Kernighan and Ritchie을 읽어 보시기 바랍니다? 'memcpy'에 주어진 포인터가 유효한지 확인 했습니까? –

+0

codepad.I 사용하고 있습니다. C 소프트웨어가 설치되어 있지 않습니다. – Angus

+0

@Angus : 하나 사주세요. – 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에 확실한 방법입니다.

두 번째로 매개 변수로 함수에 전달 된 배열에서 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)과 비슷해야하므로 개체를 직접 사용할 수 있습니다. 존재에이 일을 디버깅하려고 C.가

1

당신이 sizeof(data)을 사용할 수 없습니다! 반환되는 크기는 포인터의 포인터가 아닌 포인터입니다. 함수 AIUP_readAIUP_write에 데이터 길이를 제공해야합니다.

+0

나는 strlen (data)와 strlen (user_mem [pos])을하고있다. 이게 맞습니까. 도움이 – Angus

1

귀하의 충돌 AIUP_write에 : 당신이 이렇게 (vol_level의 값을 출력하는 '% d 개'로 변경) 충돌, 문자열을 읽으려고하는

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

.

(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

좋아하는 거기 :

는 sizeof 연산자의 사용 및 디버거가 아주 쉽게이 문제를 보여줍니다 항상 0

입니다 pos의 사용에 관련된 다른 논리 문제가 있습니다 몇 가지 문제가 있습니다. 첫째, sizeof의 사용이 잘못되었습니다. 각각의 경우에 읽기/쓰기 및 audio_state 구조를 사용하는 것처럼 보이므로 sizeof(audio_state)을 사용하여 전체 구조를 복사해야합니다. sizeof(user_mem[pos]), 당신의 printf 문이 또 다른 하나의 경우 %c%s을 사용하는 두 번째 1

될 것입니다 동안 sizeof(data) 아마도 64 비트 시스템에서 32 비트 머신과 8에 당신에게 4 줄 것이다. 나는 독방 감금 - 고장의 원인이 라인 의심 :

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

당신은 문자열의 (a char*)를 기대하는 printf을 이야기하고 있지만, 당신은 unsigned char입니다 *data를 전달하고 있습니다. printf은이 문자를 char*에 전송하고 주소에 액세스하려고 시도합니다. 그것은 문자열이 아니기 때문에 잘못 될 것입니다.

+0

숀 : 당신 말이 맞아요!. 나는 오류가 없다. 그러나 출력물을 출력 할 수 없습니다. 편집을 참조하십시오. – Angus

+0

실수가 어디에 있는지 확인하는 데 도움을주십시오!. – Angus