2011-11-11 3 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. Пожалуйста, помогите мне решить эту проблему.seg fault in memcpy()

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

ли вы запустить его через отладчик? Вы проверили, что указатели, указанные в «memcpy», были действительны? –

+0

Я использую codepad. У меня нет программного обеспечения C. – Angus

+0

@Angus: Я предлагаю вам его получить. – leppie

ответ

3

Во-первых, ваше использование read() и write() теней система поставляемыми read(2) и write(2) рутин. Это гигантская ошибка. (You может заменить системные обертки системного вызова, но вам лучше убедиться, что вы выполняете такую ​​же работу, как программирование их, как это делали авторы библиотеки C. Во-первых, у вас нет . входящие в комплект read(2) и write(2) функции делают.) Ваш вызов printf(3) попытается использовать write(2) внутренне, чтобы написать свой вывод и вместо этого найдет вашу реализацию.Поскольку ваш обрабатывает свои параметры совсем по-другому, чем реализация write(2), он, вероятно, умрет на этом вызове memcpy() - вы разыменовали первый аргумент write(), как если бы это был указатель, но printf(3) будет называть его целым числом, например 1. Вызов разыменования 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), поэтому вы можете напрямую работать с объектами.

Я настоятельно рекомендую прочитать The C Programming Language by Kernighan and Ritchie, прежде чем тратить гораздо больше времени на эту программу - пытается отладить этот в существование будет быть мучительно медленный путь, чтобы узнать C.

1

В AIUP_read вы не можете использовать sizeof(data)! Возвращаемый размер будет отображаться как указатель , а не то, на что он указывает. Вы должны указать длину данных для функций AIUP_read и AIUP_write.

+0

Я делаю strlen (данные) и strlen (user_mem [pos]). Правильно ли это. Помощь в помощи – Angus

1

Ваш крах в AIUP_write:

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

вы пытаетесь прочитать строку, таким образом, сбой (изменение в «% г», чтобы напечатать значение 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); 
1

Хорошо, что есть пара проблем. Во-первых, ваше использование sizeof кажется неправильным. В каждом случае, похоже, вы пытаетесь читать/писать и audio_state, поэтому для копирования всей структуры вы должны использовать sizeof(audio_state). sizeof(data), вероятно, даст вам 4 на 32-битной машине и 8 на 64-битной машине, в то время как sizeof(user_mem[pos]) будет 1.

Во-вторых, ваши printf заявления используют %c в одном случае и %s в другой. Я подозреваю, что причина SEG-вины является линия:

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

Вы говорите printf ожидать строку (char*), но вы передаете в *data, который является unsigned char. printf будет передавать этот символ char* и попытаться получить доступ к этому адресу. Поскольку это не строка, она будет виновата.

+0

Шон: вы правы !. У меня нет ошибок. Но выход не может быть распечатан. Пожалуйста, см. Редактирование – Angus

+0

. Пожалуйста, помогите мне определить, где ошибка !. – Angus