2016-07-05 3 views
1
char *test={"0x11","0x12","0x13","0x00","0x00"}; 
void change(char* test1, char* test2){ 
    strncpy(test[3], test1, 4); 
    strncpy(test[4], test2, 4); 
} 

chage("0x55","0x66"); 

Я могу присвоить символы элементу массива напрямую. Однако это приведет к утечке памяти. Вот почему я использую вместо этого strncpy().C - использование strncpy - segfault

Пожалуйста, сообщите, если вы знаете, как это исправить.

+8

Включите предупреждения своего компилятора: '-pedantic -Wall -Werror -std = c11'. –

+0

По какой-то причине тест инициализируется массивом строк (char **). Интересно, как это работает в первую очередь. –

+0

Интересно, как вы не получаете синтаксических ошибок во многих местах в последней строке (0x66 - это число, а не строка и может быть неявно преобразовано в недействительный указатель) –

ответ

4

Есть, по крайней мере, три два, вы можете получить segfault здесь (одно предложение - включить предупреждения компилятора - они часто забирают «глупые ошибки»).

Проблема заключается в том, что test вероятно misdeclared, это, вероятно, были:

char *test[]={"0x11","0x12","0x13","0x00","0x00"}; 

Вы инициализировать char* с массивом char*, который означает, что вы инициализировать test с первым указателем в массиве - который означает, что test будет указывать на строковый литерал "0x11", поэтому, когда вы используете test[3] в качестве аргумента strncpy, вы отправите 1, который преобразуется в указатель (возможно, по адресу 0x31). strncpy попытался бы написать тот адрес, который, скорее всего, не разрешен. У вас была почти четвертая причина здесь, если вы использовали test[5], вы попросили бы получить доступ за пределами строки, которая запрещена (вы можете получить доступ к test[4], потому что это завершающий нуль строки).

Даже если вы устраните эти проблемы, возникает проблема, потому что test[3] и test[4] инициализируются с использованием строкового литерала. Затем strncpy попытается изменить этот строковый литерал, который является неопределенным поведением - segfault является потому, что test[3] и test[4] находятся в постоянной памяти (позволяя им находиться в постоянной памяти - одна из причин, по которой изменение строковых литералов является неопределенным поведением).

Что вы могли бы сделать, это убедиться, что у вас есть записываемые копии в test, что, возможно, не так прямо в C. Одно нормальное решение - иметь функцию (которую вы должны вызывать вручную), которая настраивает test, и один, что слезы его вниз:

void init_test(void) { 
    int j; 

    for(j=0; j<sizeof(test)/sizeof(test[0]); j++) 
     test[j] = strdup(test[j]); 

} 

void init_fini(void) { 
    int j; 

    for(j=0; j<sizeof(test)/sizeof(test[0]); j++) 
     free(test[j]); 
} 
0

другой ответ дает одну причину (не пытаться изменить содержимое из строки (строка (п) КПЮ делает это)).

Я даже не уверен, что вы хотите представлять «символы» в виде строк, тем более, что первое объявление не работает (присвоение массива строк строке).

Это займет много времени, чтобы исправить это точно, но вы должны начать с замены «0x11» на «\ x11» (IE фактически использует символы), заменить strncpy простым назначением (истинные символы являются атомным типом которые могут быть назначены напрямую) и, наконец, изменить параметры функции изменения, чтобы получить символы вместо строк.

Смежные вопросы